Compare commits

..

90 Commits

Author SHA1 Message Date
Paul Beckingham
c393d47cdf - Corrected bogus .gitignore entry that blocked src/tests/Makefile. 2008-06-13 01:51:51 -04:00
Paul Beckingham
3525b6db2c - Added Bruce Israel for his suggestion of subprojects. 2008-06-13 01:25:38 -04:00
Paul Beckingham
d50efe5e27 - Updated versions 2008-06-13 01:18:53 -04:00
Paul Beckingham
2c0a1ddb3a - Added new feature for 1.2.0 2008-06-13 01:15:49 -04:00
Paul Beckingham
d7ac37783c - Updated documentation to include subproject discussions.
- Added Richard Querin to the AUTHORS file for his contribution of ideas and a .deb package.
2008-06-13 01:02:17 -04:00
Paul Beckingham
03bb50c4ea - Corrected copyright display. 2008-06-13 00:19:54 -04:00
Paul Beckingham
1535010ac9 - "Age" column is now optional for the "list" and "next" reports. 2008-06-13 00:18:28 -04:00
Paul Beckingham
8d90035bbc - Now properly parses dates according to specified date format. 2008-06-12 23:58:58 -04:00
Paul Beckingham
fd7bb9daa9 - Support subprojects. 2008-06-11 02:19:00 -04:00
Paul Beckingham
88b12bc66a - Added caseless keyword comparison to the autocolorization rules. 2008-06-11 01:47:11 -04:00
Paul Beckingham
a8ac82ca22 - Added "What's new in 1.2.0" section. 2008-06-11 01:45:07 -04:00
Paul Beckingham
438f3cb134 - Added caseless comparison when searching keywords in the description. 2008-06-11 01:40:01 -04:00
Paul Beckingham
131693f617 - Fixed bug whereby the "dateformat" configuration variable was being used to display dates, but not parse them. 2008-06-11 01:14:22 -04:00
Paul Beckingham
07d1f63e31 - Bumped version to 1.2.0 2008-06-10 22:59:43 -04:00
Paul Beckingham
73286e8662 - Cleaned up visible copyright.
- Added a "what's new" list to task.html
2008-06-07 23:29:32 -04:00
Paul Beckingham
95c3f78c68 - Added tags to the "long" report. 2008-06-07 23:13:07 -04:00
Paul Beckingham
90df505982 - Added Google AdSense to the task.html page. 2008-06-07 22:53:18 -04:00
Paul Beckingham
e8b7114ce8 - Added the ability to control date formats via the 'dateformat' configuration variable. 2008-06-07 17:09:09 -04:00
Paul Beckingham
714d9c5544 - Included new changes 2008-06-07 13:28:27 -04:00
Paul Beckingham
f2ba9f796b - Bumped version to 1.1.0 2008-06-07 13:23:59 -04:00
Paul Beckingham
e025ecc3d4 - Configurable extra white space via "blanklines" configuration variable. 2008-06-07 13:23:39 -04:00
Paul Beckingham
ccd2b9fc44 - Added Cygwin to the platform list.
- Added missing items to the TUTORIAL file.
- Converted TUTORIAL to HTML, in task.html.
2008-06-06 01:38:37 -04:00
Paul Beckingham
6cb902c499 - Home page update. 2008-06-05 21:08:37 -04:00
Paul Beckingham
d216d40121 - Now points to 1.0.1 2008-06-04 21:22:45 -04:00
Paul Beckingham
08f4ead97e - Fixed bug whereby the UUID generated by the custom generator was not terminated.
- Fixed bug whereby random numbers were used by the custom UUID generator, but srandom/srand was not called first.
2008-06-04 21:00:23 -04:00
Paul Beckingham
f3de5c0711 - Added bare-bones task.html to point to the latest version. 2008-06-04 19:26:35 -04:00
Paul Beckingham
89d4dd74da - Corrected platform list. 2008-06-03 23:23:22 -04:00
Paul Beckingham
9ff83281c5 - Updated ChangeLog. 2008-06-03 23:17:11 -04:00
Paul Beckingham
787b3b4a51 - Added YouTube reference to new movie.
- Corrected coloration in "task calendar" command.
2008-06-03 23:16:40 -04:00
Paul Beckingham
74e77e4dc5 - Added legend to "task calendar" output 2008-06-03 09:09:52 -04:00
Paul Beckingham
f73c64801c - Added three new colorization rules - color.tag.x, color.project.x, color.keyword.x.
- Updated default .taskrc file.
- Updated docs accordingly.
2008-06-03 09:00:51 -04:00
Paul Beckingham
039c3119ff - problem on Solaris 10 fixed, docs updated 2008-06-02 10:54:54 -04:00
Paul Beckingham
fb9f5e2ab3 - Editorial 2008-06-01 22:20:24 -04:00
Paul Beckingham
3077c50774 - "calendar" command now uses oldest and newest due dates for limits. 2008-06-01 15:44:26 -04:00
Paul Beckingham
0ec24aaef5 - Added spoken parts, improved commands. 2008-06-01 13:44:02 -04:00
Paul Beckingham
1a580b1967 - Removed unnecessary TODO items from the source code. 2008-05-30 22:10:06 -04:00
Paul Beckingham
fd8f63dec6 - Removed debugging, obsolete code. 2008-05-30 22:07:06 -04:00
Paul Beckingham
7c9554e8c5 - Modified AUTHORS file.
- Added announcement.txt file for the mailing list.
2008-05-30 22:00:19 -04:00
Paul Beckingham
f57e22124f - Added text to README file. 2008-05-30 21:41:06 -04:00
Paul Beckingham
9aec4efefa - Added proper copyright, licensing details to all source.
- Eliminated redundant stlmacros.h heaer file.
2008-05-30 21:35:49 -04:00
Paul Beckingham
8a0b8e0328 - Updated all documents. 2008-05-30 21:22:22 -04:00
Paul Beckingham
1aa9051885 - Fixed bug whereby a % character could not be used in a description. Problem was use of fprintf, which when changed to fputs, fixed the problem. 2008-05-30 20:59:28 -04:00
Paul Beckingham
654eb260c7 - Recorded new "task calendar" behavior. 2008-05-30 20:24:53 -04:00
Paul Beckingham
b061ef6191 - "task calendar" now lists all months that contain pending due tasks. 2008-05-30 20:22:38 -04:00
Paul Beckingham
86a9f0f6d5 - Release candidate 1
- Fixed bug where stats were gibberish whne there were no tasks, ie a new user.
2008-05-29 10:33:56 -04:00
Paul Beckingham
0bf87ed311 - Fixed bug where "task version" asserted on mobile device. 2008-05-28 10:53:24 -04:00
Paul Beckingham
abc9aa08ec - Fixed bug where "task projects" rendered an empty table instead of saying "no projects". 2008-05-27 21:03:27 -04:00
Paul Beckingham
a42b8a89c3 - Completed 0.9.9 2008-05-27 20:47:56 -04:00
Paul Beckingham
011ad8fafd - Documentation snapshot, version bump. 2008-05-27 16:05:54 -04:00
Paul Beckingham
586883a98d - Updated status in ChangeLog. 2008-05-26 21:40:56 -04:00
Paul Beckingham
40dc0490e1 - Removed unused variable only detectable on Ubuntu 8.
- Removed misplaced files.
2008-05-26 21:39:10 -04:00
Paul Beckingham
abef040ebc Merge branch 'fedora9'
Conflicts:

	src/Date.cpp
	src/Table.cpp
2008-05-26 21:14:34 -04:00
Paul Beckingham
cb4f86e9f1 - Changes necessary for a clean build on Fedora9. 2008-05-26 20:58:41 -04:00
Paul Beckingham
b8fc8a0172 - Changes to enable a clean build on Ubuntu 8. 2008-05-26 14:58:45 -04:00
Paul Beckingham
35dd5df583 Merge branch 'fedora8' 2008-05-26 14:45:59 -04:00
Paul Beckingham
e666772477 - Added bugs to ChangeLog 2008-05-26 14:17:59 -04:00
Paul Beckingham
6b07f04338 Merge branch 'master' into fedora8 2008-05-26 14:17:13 -04:00
Paul Beckingham
334eb45534 - Corrected improperly specified color in sample .taskrc 2008-05-26 14:04:15 -04:00
Paul Beckingham
5e6b256df5 - Changes to enable a clean build under Fedora 8. 2008-05-26 13:34:33 -04:00
Paul Beckingham
e392b8a95e - Added portability documentation. 2008-05-26 13:31:19 -04:00
Paul Beckingham
18fd59a1ed - Bumped to 0.9.8 2008-05-25 20:36:13 -04:00
Paul Beckingham
4549af6b84 - Added DEVELOPERS file describing high-level code layout.
- Removed unused library.h file.
- Removed unused std::wstring Unicode variants.
2008-05-25 20:33:27 -04:00
Paul Beckingham
4825b37df5 - Added color command. 2008-05-25 01:01:24 -04:00
Paul Beckingham
148088c775 - Removed overwriting of colors in autoColorize. 2008-05-24 23:32:29 -04:00
Paul Beckingham
45a25ca47b - Fixed Table::calculateColumnWidths bug. 2008-05-24 23:08:36 -04:00
Paul Beckingham
ab0a57ec89 - Documentation cleanup 2008-05-20 00:05:18 -04:00
Paul Beckingham
65c2fe438f - Migrated old compiler flags for better warnings, etc 2008-05-19 23:28:48 -04:00
Paul Beckingham
37bdfe06da - Added endwin check to configure.ac 2008-05-19 10:48:01 -04:00
Paul Beckingham
b54b07ef77 Merge branch 'master' of git@github.com:pbeckingham/task
Conflicts:

	ChangeLog
2008-05-19 00:25:27 -04:00
Paul Beckingham
e3eb87aa74 - Snapshot 2008-05-18 00:32:27 -04:00
Paul Beckingham
b34cb90709 - Set up structure for AUTHORS file.
- Set up NEWS file, with pleas for feedback.
- Added welcome message to README.
- Completed a chunk of the TUTORIAL.
- Added error handling for "task export" when a file name is not specified.
2008-05-18 00:30:12 -04:00
Paul Beckingham
04da56193e - Removed unnecessary SAMPLE_taskrc, and assorted references.
- Cleaned up ChangeLog.
- Minor mods to standard docs.
2008-05-17 23:16:08 -04:00
Paul Beckingham
25dc415094 - Bumped version to 0.9.7
- Changed some autoconf details
- Corrected comment in T.cpp
2008-05-17 22:47:51 -04:00
Paul Beckingham
0b37b6a980 - Made unit tests compile nad run again.
- Removed tests from distibution.
2008-05-17 22:46:50 -04:00
Paul Beckingham
42493dbdee - Task offers to create a sample ~/.taskrc file if one is not found.
- Task offers to create a ~/.task directory if one is not found.
2008-05-17 22:08:50 -04:00
Paul Beckingham
3e1afc5777 - ChangeLog snapshot 2008-05-16 16:55:09 -04:00
Paul Beckingham
a8fa293695 - Corrected wrong include file in Table.cpp 2008-05-15 11:33:46 -04:00
Paul Beckingham
e7341a19cf - Bumped version for next release. 2008-05-14 00:16:37 -04:00
Paul Beckingham
2ecf500322 - Corrected colorization rules parsing. 2008-05-13 23:38:22 -04:00
Paul Beckingham
494ed3b964 - New color management integrated. 2008-05-13 23:08:25 -04:00
Paul Beckingham
53747cc984 - Updated ChangeLog
- Added original design decisions to README
2008-05-13 00:08:04 -04:00
Paul Beckingham
b63cf606f0 - Integrated Grid object for data storage.
time ./task lo

			old	new
		real	0.262	0.018
		user	0.201	0.013
		sys	0.048	0.004

		~1200-1400% faster

	time ./task completed

			old	new
		real	3.991	4.014
		user	2.821	2.832
		sys	1.165	1.169

		~0.3-0.5% slower
2008-05-12 23:29:14 -04:00
Paul Beckingham
3dd45611ff - Added Grid.cpp to configure.ac
- Added Makefile to src/.gitignore
2008-05-10 22:10:01 -04:00
Paul Beckingham
e32d0562a2 - Makefile should not be part of the repository. 2008-05-10 22:08:52 -04:00
Paul Beckingham
a991cbf242 - Added Grid.cpp 2008-05-10 22:07:25 -04:00
Paul Beckingham
2e047367b0 - Added Grid::Cell::operator== 2008-05-10 22:06:20 -04:00
Paul Beckingham
f9ed90bee0 - ChangeLog file begun.
- Bumped version to 0.9.5 for next release.
2008-04-27 11:02:25 -04:00
Paul Beckingham
62e6b31a17 - Integrated new Grid object into build - not yet integrated into Table. 2008-04-26 00:09:59 -04:00
Paul Beckingham
ce52f88f4b - More .gitignore tweaks. 2008-04-19 22:43:42 -04:00
Paul Beckingham
6d5de69f90 - Added .gitignore 2008-04-19 22:29:53 -04:00
58 changed files with 5043 additions and 1574 deletions

13
.gitignore vendored Normal file
View File

@@ -0,0 +1,13 @@
Makefile.in
aclocal.m4
autom4te.cache
auto.h*
config.h.in
config.status
src/.deps
src/Makefile
src/task
stamp-h1
Makefile
configure
config.log

10
AUTHORS
View File

@@ -0,0 +1,10 @@
Principal Author:
Paul Beckingham, paul@beckingham.net
With thanks to:
Eugene Kramer
SK
Damian Glenny
Richard Querin
Bruce Israel

59
COPYING
View File

@@ -278,63 +278,4 @@ PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

185
ChangeLog
View File

@@ -1,16 +1,183 @@
Version numbers are of the form:
0.9.2
4/3/2008
- Configure now detects ncurses, flock.
x.y.z
where the x represents a major version number, or architecture. The y
represents a feature release, and the z represents a patch.
0.9.1
4/1/2008
- First autoconf version released.
- Bug: due dates not checked for correctness
- Bug: attributes without values stored instead of removed
------ plans -------------------------------------
Configurable columns in reports
0.9.0
------ reality -----------------------------------
1.2.0 (6/13/2008)
+ Bug: "dateformat" configuration variable used to display dates, but
not parse them
+ "task list x" now performs a caseless comparison between "x" and the
description
+ Task sub projects supported
+ "showage" confguration determines whether "Age" column appears on the
"list" and "next" reports
+ Improved TUTORIAL
1.1.0 (6/7/2008)
+ "blanklines" configuration to stop displaying unnecessary white
space and thus work better on small-screen devices
+ "dateformat" configuration now determines how dates are formatted
+ Better formatting of "task tags" output
+ http://www.beckingham.net/task.html home page set up
+ Added tags to the "task long" report
1.0.1 (6/4/2008)
+ Bug: UUID generator not properly terminating string.
+ Bug: srandom/srand not called prior to UUID generation.
1.0.0 (6/3/2008)
+ New movie made, uploaded
+ Bug: assertion fails on mobile for t v
+ Bug: configure.ac does not properly determine ncurses availability
+ Bug: Cannot seem to use the percent character in a task description
+ Bug: New installation "task stats" reports newest task 12/31/1969
+ Bug: New installation task projects displays header but no data - should short-circuit
+ Bug: incorrect color specification in sample .taskrc file
+ Bug: when run without arguments, task dumps core on Solaris 10
+ "task calendar" now reports all months with due pending tasks
+ Added rules for colorization by tag, project and keyword
+ Added legend to "task calendar"
0.9.9 (5/27/2008)
+ Autoconf/automake behaving properly.
+ Clean build on OS X 10.5.
+ Clean build on Ubuntu 8.0.
+ Clean build on Fedora Core 8.
+ Clean build on Fedora Core 9.
0.9.8 (5/25/2008)
+ Added "task color" command.
+ Removed unnecessary files.
+ Completed documentation.
0.9.7 (5/24/2008)
+ Migrated old compiler flags into Makefile.am
+ Added ncurses endwin function check to configure.ac
+ Set up structure for AUTHORS file.
+ Set up NEWS file, with pleas for feedback.
+ Added welcome message to README.
+ Completed a chunk of the TUTORIAL.
+ Added error handling for "task export" when a file name is not specified.
+ Task offers to create a sample ~/.taskrc file if one is not found.
+ Task offers to create a ~/.task directory if one is not found.
+ Removed unnecessary SAMPLE_taskrc, and assorted references.
+ Cleaned up ChangeLog.
+ Minor mods to standard docs.
+ Bumped version to 0.9.7
+ Changed some autoconf details
+ Corrected comment in T.cpp
+ Made unit tests compile and run again.
+ Removed tests from distibution.
0.9.6 (5/13/208)
+ Corrected wrong include file in Table.cpp
+ Replaced color management code.
+ Improved color rules code.
0.9.5 (5/12/2008)
+ Replaced Table storage with Grid.
+ Added Grid.cpp to configure.ac
+ Added Makefile to src/.gitignore
+ Makefile should not be part of the repository.
+ Added Grid.cpp
+ Added Grid::Cell::operator==
+ ChangeLog file begun.
+ Bumped version to 0.9.5 for next release.
0.9.4 (4/26/2008)
+ Integrated new Grid object into build - not yet integrated into Table.
+ More .gitignore tweaks.
+ Added .gitignore
+ Added more missing files.
+ Added all source code.
+ Generic OSS files added.
+ Initial commit.
0.9.3 (4/6/2008)
+ Added "task completed" command.
+ Properly recognizes ncurses.
0.9.2 (4/3/2008)
+ Recognizes whether ncurses, flock is available.
+ "task" duplicated to "task_rel" for preparation of a fork.
0.9.1 (4/1/2008)
+ Blank attributes read are longer be written out.
+ Completed "task export" command.
+ Added configuration values to "task version" command.
+ Consolidated header files, removed unnecessary ones.
0.9.0 (3/23/2008)
+ flat source directory
+ autoconf complete
+ "task next"
+ "task stats"
+ "task export"
+ Rules-based colorization
0.8.1 (1/28/2008) - 0.8.16 (3/13/2008)
+ autoconf conversion (many builds)
0.8.0 Polish (1/25/2008)
+ Code cleanup, reorganization
+ "task overdue"
+ Add "age" column to list and long
+ Use 'conf' for build, version tracking
+ Add "/from/to/" description editing
0.7.0 Multi-user, File handling, atomicity (1/8/2008)
+ Clean, publishable API reimplementation
+ File locking
+ retain deleted tasks
+ "task info ID" report showing all metadata
+ File format v2
[Development hiatus while planning for T, TDB API, new features and the future
of the project. Seeded to two testers for feedback, suggestions.]
0.6.0 Reports (12/27/2006)
+ "task history"
+ "task summary"
+ "task calendar"
+ due support
+ Table sorting
0.5.0 Multi-user support (12/10/2006)
+ Command logging
+ "task usage" report
0.4.0 Destructive / modification commands (12/3/2006)
+ "task delete" complete
+ "task id ..." complete
+ "task list ..." synonym for "task find ..."
0.3.0 Work in progress support (12/3/2006)
+ "task start" complete
+ "task done" complete
+ completed.data support
0.2.0 Neutral commands (12/2/2006)
+ "task find" complete
+ "task projects" complete
+ "task tags" complete
0.1.0 Constructive commands (12/1/2006)
+ "task add" complete
+ completed.data support
+ ~/.taskrc support
0.0.1 Basic infrastructure (11/29/2006)
+ Command line parsing
+ API layer
+ Usage
------ start -----------------------------------

20
DEVELOPERS Normal file
View File

@@ -0,0 +1,20 @@
Developers may wish to change task, and here is a high-level guide to the files
included.
task.{cpp,h} Functions that implement the task commands, and main.
parse.cpp Parses the command line.
TDB.{cpp,h} The task database, performs all file I/O
T.{cpp,h} Represents a single task - parses a record from TDB, and also
composes record for TDB. Provides accessors for tasks.
Grid.{cpp,h} Implements a sparse 2D array, provides data storage for the
Table object.
Table.{cpp,h} Implements tabular data rendering, wrapping etc.
Config.{cpp,h} Implements a reader for the .taskrc file.
Date.{cpp,h} General date class for the time_t type.
text.cpp Text manipulation functions.
util.cpp General utility functions.
color.cpp Color support functions.
rules.cpp Auto-colorization rules.
Don't forget, please send bugs, patches to task@beckingham.net

View File

@@ -1,3 +1,3 @@
SUBDIRS = src
EXTRA_DIST = TUTORIAL SAMPLE_taskrc
EXTRA_DIST = TUTORIAL DEVELOPERS

29
NEWS
View File

@@ -1,4 +1,31 @@
Welcome to Task 1.2.0.
Task 1.0 is released.
Task has been built and tested on the following configurations:
- OS X 10.4 Tiger
- OS X 10.5 Leopard
- Fedora Core 8
- Fedora Core 9
- Ubuntu 8 Hardy Heron
- Solaris 10
- Cygwin 1.5.25-14
While Task has undergone testing, bugs are sure to remain. If you encounter a
bug, please contact me at task@beckingham.net. Here is what you could do, in
order of increasing effort (to you) and usefulness (to me):
- Do nothing. Bug probably won't get fixed.
- Send an email to task@beckingham.net, explaining what you saw. The bug
will be addressed, and a new release will be made. You will be a hero.
- Send an email, and a reproducible test case in the form of the few commands
it takes to recreate the problem. The bug will be addressed, and a new
release will be made. You will be a hero.
- If you are a developer, send a patch that fixes the problem. Your patch
will be applied and tested, and a new release will be made. You will be a
hero.
Thank you.

51
README
View File

@@ -1,7 +1,48 @@
Thank you for taking a look at task. Task is a GTD utility featuring:
Thank you
GTD
Based on ideas in todo.sh
Movie at www.b.n/task.mov
Feedback, suggestions to task@beckingham.net
- Robust C++ implementation
- Tags
- Colorful, tabular output
- Reports
- Lots of commands
- Low-level API
- Abbreviations for all commands, options
- Multi-user file locking
- Clean architecture allowing quick addition of new features
It is intended that features, mainly in the form of reports will be added
frequently, with best practices and useful reports evolving from usage patterns.
Task is scope-limited to GTD functionality only.
You may want to jump straight to the TUTORIAL file, or perhaps watch the old
task movie on YouTube:
http://www.youtube.com/watch?v=l68LCl6BYvs
or the new improved one:
http://www.youtube.com/watch?v=D2Kn4DMOVSw
Either will give you a fairly good idea of what task is capable of, and whether
it fits in to your way of working. As a command line application, task is not
for everyone and some of you may prefer to not proceed. The movie or TUTORIAL
file are the quickest way for you to make that decision.
Task is based on ideas presented in the todo.sh script, found on:
http://todotxt.org
Task has a few more features than todo.sh, but fundamentally, they are both
working toward the same goals, which is to help you follow basic Getting Things
Done (GTD) principles.
All feedback is welcome, in addition to any bug reports or patches to:
task@beckingham.net
Got an idea for an enhancement? Send a message!
I have found that task makes me more productive and organized. I hope task can
do the same for you.

View File

@@ -1,15 +0,0 @@
data.location=/home/bob/.task
#command.logging=on
confirmation=yes
nag=Note: try to stick to high priority tasks. See "task next".
next=2
#color.overdue=red
#color.due=on yellow
#color.pri.H=red
#color.pri.M=yellow
#color.pri.L=green
#color.pri.none=white on yellow
#color.active=blue
#color.tagged=yellow

656
TUTORIAL
View File

@@ -1,9 +1,18 @@
Task program tutorial, for version 0.9.0
Task program tutorial, for version 1.2.0
----------------------------------------
This guide shows how to quickly set up the task program, and become proficient
with it.
Contents:
Quick Setup
Simple Usage
Advanced Usage
Interacting with the Shell
Configuring Task
Colors
Quick Setup
-----------
@@ -12,32 +21,35 @@ Build the task program according to the directions in the INSTALL file. This
transcript illustrates a typical installation:
% ls
task-0.9.0.tar.gz
% gunzip task-0.9.0.tar.gz
% tar xf task-0.9.0.tar
% cd task-0.9.0
task-1.2.0.tar.gz
% gunzip task-1.2.0.tar.gz
% tar xf task-1.2.0.tar
% cd task-1.2.0
% ./configure
...
% make
...
% make install
% make install # (may require sudo, depending on --prefix)
You need to make sure that the installed task program is in your PATH
environment variable. The next step is to create a configuration file for the
task program. This file resides in your home directory, is called .taskrc, and
contains various configuration settings. Use the provided SAMPLE_taskrc file
as a starting point for your own:
environment variable.
% cp SAMPLE_taskrc ~/.taskrc
% mkdir ~/.task
Task reads a configuration file - called .taskrc in your home directory - and
stores pending and completed tasks in in a directory specified in the
configuration file.
Your .taskrc files contains an entry that points to the .task directory
belonging to user bob. Change this entry to point to your own home directory,
and the .task directory you just created. Your task program is now ready to
use. Verify that task is properly installed with:
The simplest way to get a configuration file and task directory is to run task.
On startup, task will check to see if it can find the configuration file and
task directory, and if not found, will ask you whether it may create both.
% task version
[show sample output]
A configuration file could not be found in /Users/paul/.taskrc
Would you like a sample .taskrc created, so task can proceed? (y/n) y
Done.
[then task will show version information]
Simple Usage
@@ -55,7 +67,7 @@ interface. Let us take a look at those tasks:
% task ls
ID Project Pri Description
ID Project Pri Description
1 Book plane ticket
2 Rent a tux
3 Reserve a rental car
@@ -70,21 +82,22 @@ task 2:
Permanently delete task? (y/n) y
Task wants you to confirm deletions. To remove the confirmation, edit your
.taskrc file and remove the line:
.taskrc file and change the line:
confirmation=yes
or change the yes to no.
to have a value of "no".
While projects and priorities are not necessary, they can be very useful when
the list of tasks grows large. Let's assign a project to these tasks:
While the use of projects and priorities are not essential to benefitting from
task, they can be very useful when the list of tasks grows large. Let's assign
a project to these tasks:
% task 1 project:Wedding
% task 3 project:Wedding
% task 4 project:Family
% task ls
ID Project Pri Description
ID Project Pri Description
3 Family Send John a birthday card
2 Wedding Reserve a rental car
1 Wedding Book plane ticket
@@ -92,13 +105,48 @@ the list of tasks grows large. Let's assign a project to these tasks:
Notice that the id numbers have changed. When tasks get deleted, or have their
attributes changed (project, for example), the ids are prone to change. But the
id numbers will remain valid until the next 'ls' command is run. You should
only use the ids from the most recent 'ls' command.
only use the ids from the most recent 'ls' command. The ids change, because
task is always trying to use small numbers so that it is easy for you to enter
them correctly.
Subprojects are supported. If you have a project "Wedding", you can specify
that a task is a subproject "Transport" of "Wedding" by assigning the project
"Wedding.Transport". Let's do this:
% task 2 project:Wedding.Transport
% task ls
ID Project Pri Description
3 Family Send John a birthday card
2 Wedding.Transport Reserve a rental car
1 Wedding Book plane ticket
Task matches the leftmost part of the project when searching, so projects
may be abbreviated:
% task ls project:Wedding.Tra
ID Project Pri Description
2 Wedding.Transport Reserve a rental car
This way of matching projects can be used to see all tasks under the
"Wedding" project and all subprojects:
% task ls project:Wedding
ID Project Pri Description
2 Wedding.Transport Reserve a rental car
1 Wedding Book plane ticket
Let's reassign 2 back to the "Wedding" project:
% task 2 project:Wedding
Now that projects are assigned, we can look at just the Wedding project tasks:
% task ls project:Wedding
ID Project Pri Description
ID Project Pri Description
1 Wedding Book plane ticket
2 Wedding Reserve a rental car
@@ -107,14 +155,14 @@ could also have requested:
% task ls ticket plane
ID Project Pri Description
ID Project Pri Description
1 Wedding Book plane ticket
Now let's prioritize. Priorities can be H, M or L (High, Medium, Low).
% task ls
ID Project Pri Description
ID Project Pri Description
3 Family Send John a birthday card
2 Wedding Reserve a rental car
1 Wedding Book plane ticket
@@ -126,7 +174,7 @@ Now let's prioritize. Priorities can be H, M or L (High, Medium, Low).
% task 3 pri:H
% task ls
ID Project Pri Description
ID Project Pri Description
3 Family H Send John a birthday card
1 Wedding H Book plane ticket
2 Wedding M Reserve a rental car
@@ -136,37 +184,44 @@ Priority can be abbreviated to pri, but not pr, because it is ambiguous. Now
that tasks have been prioritized, you can see that the tasks are being sorted
by priority, with the highest priority tasks at the top.
These attributes can all be provided when the task is added, instead of
applying them afterwards, as shown. The following command shows how to set all
the attributes at once:
% task add project:Wedding priority:H Book plane ticket
The 'ls' command provides the least information for each task. The 'list'
command provides more:
% task list
ID Project Pri Due Active Age Description
ID Project Pri Due Active Age Description
3 Family H 4 mins Send John a birthday card
1 Wedding H 5 mins Book plane ticket
2 Wedding M 5 mins Reserve a rental car
Notice that task can have a due date, and can be active. The task lists are
Notice that a task can have a due date, and can be active. The task lists are
sorted by due date, then priority. Let's add due dates:
% task 3 due:3/25/2008
% task 1 due:5/31/2008
% task 3 due:6/25/2008
% task 1 due:7/31/2008
% task list
ID Project Pri Due Active Age Description
3 Family H 3/25/2008 6 mins Send John a birthday card
1 Wedding H 5/31/2008 7 mins Book plane ticket
ID Project Pri Due Active Age Description
3 Family H 6/25/2008 6 mins Send John a birthday card
1 Wedding H 7/31/2008 7 mins Book plane ticket
2 Wedding M 7 mins Reserve a rental car
If today's date is 3/23/2008, then task 3 is due in 2 days. It will be colored
If today's date is 6/23/2008, then task 3 is due in 2 days. It will be colored
yellow if your terminal supports color. To change this color, edit your
.taskrc file, and change the line to one of these alternatives:
color.due=<foreground color> on <background color>
color.due=<foreground color>
color.due=on <background color>
color.due=red
color.due=on_blue
color.due=red on_blue
color.due=bold_red on_blue
Where color is one of:
Where color is one of the following:
black
blue
@@ -178,38 +233,507 @@ Where color is one of:
white
All colors are specified in this way. Take a look in .taskrc for all the other
colors you control.
color rules that you control.
Tagging tasks is a good way to group them, aside from specifying a project. To
add a tag to a task:
% task <id> +tag
The plus sign indicates that this is a tag. Any number of tags may be applied
to a task, and then used for searching. Tags are just single words that are
labels.
% task list
ID Project Pri Due Active Age Description
3 Family H 6/25/2008 8 mins Send John a birthday card
1 Wedding H 7/31/2008 9 mins Book plane ticket
2 Wedding M 9 mins Reserve a rental car
% task 1 +phone
% task 2 +phone
% task 3 +shopping
% task 3 +john
% task list +phone
ID Project Pri Due Active Age Description
1 Wedding H 7/31/2008 9 mins Book plane ticket
2 Wedding M 9 mins Reserve a rental car
To remove a tag from a task, use the minus sign:
% task 3 -john
Advanced Use
------------
Commands:
- task add
- task list
- task long
- task ls
- task done
- task completed
- task delete
- task start
- task summary
- task history
- task next
- task <modify>
- task /from/to/
- task projects
- task tags
- task info
- task active
- task overdue
- task calendar
- task stats
- task usage
- task export
- task version
Here are the other commands, in some detail. Note that the command:
% task
with no arguments will generate a help message that lists all these commands.
% task projects
---------------
This report generates a list of all the different projects that you are using
along with a count of the pending tasks for each project. For example:
% task projects
Project Tasks
Errands 1
Birthdays 3
Car 2
% task summary
--------------
This report lists all the projects and a summary of their task status.
% task summary
Project Remaining Avg age Complete 0% 100%
Errands 1 3 days 50% XXXXXXXXXXXXXXXX
Birthdays 3 7 mths 0%
Car 2 2 wks 25% XXXXXXXXX
This shows the project, the remaining tasks, the average age of each task,
the percentage completed (remaining vs total) and a bar indicating that
percentage.
% task delete <id>
------------------
There are two ways of getting rid of tasks - mark them as done, or delete
them.
% task done <id>
----------------
This is how a task is marked as done.
% task list ...
---------------
The list report will show the active status, and age of the task in addition
to the columns that "task ls" shows. It is just a more detailed list.
% task long ...
---------------
The long report will show the entry date and start date of a task, in
addition to the columns that the "task list" shows.
% task start <id>
-----------------
This marks a task as started (and therefore active), which is shown in the
"list" report:
% task list
ID Project Pri Due Active Age Description
12 Errand L Remember to deposit check
...
% task start 12
% task list
ID Project Pri Due Active Age Description
12 Errand L * 3 days Remember to deposit check
...
% task active
-------------
Shows all active tasks, that is, the tasks for which the "task start ..."
command was run, as shown above.
% task overdue
--------------
Simply lists all the task that have a due date that is past, in "list"
format.
% task history
--------------
This report shows you an overview of how many tasks were added, completed and
deleted, by month. It looks like this:
% task history
Year Month Added Completed Deleted Net
2008 March 21 16 0 5
April 13 11 1 1
May 8 14 3 -9
This shows that for the three months that task has been used, March and April
saw the total number of tasks increase, but in May the number decreased as
more task were completed than added.
% task calendar
---------------
This report shows a calendar of the current month, with any task due or
overdue dates marked on it. Color is used to mark these dates.
% task calendar
May 2008
Su Mo Tu We Th Fr Sa
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
% task next
-----------
This report shows you the tasks you should probable work on next. Task will
scan all the tasks and will pick two task from each project to report. Those
two tasks will be chosen in order of overdue, due soon, High, Medium or Low
priority. Essentially task chooses the two most important task for each
project and displays them ordered in the usual way.
If you wish to show a different number of tasks per project, modify the entry
in .taskrc:
next=2
To be your preferred number.
% task <id> ...
---------------
When a task id is specified, everything applies to just that task. Suppose
we needed to correct a task:
% task ls
ID Project Pri Description
12 Errand L Remember to deposit chekc
...
% task 12 Remember to deposit bonus check
% task ls
ID Project Pri Description
12 Errand L Remember to deposit bonus check
...
% task /from/to/
----------------
If a task has been entered with a typo, it can be easily corrected by this
command. For example:
% task ls
ID Project Pri Description
12 Errand L Remember to deposit chekc
...
% task 12 /chekc/check/
% task ls
ID Project Pri Description
12 Errand L Remember to deposit check
...
This command makes single corrections to a task description.
% task tags
-----------
This command will generate a list of all the tags that are currently in use
by task.
% task info <id>
----------------
This command gives detailed information about a single task. It will tell
you when the task was entered, when started, its status, tags, and more.
% task stats
------------
This command generates a list of statistics about your task usage, such as
the average time it takes to complete a task, how often new tasks are added,
and more.
% task completed
----------------
This generates a list of all tasks that have been completed, sorted by their
completion date.
% task export <file name>
-------------------------
This instructs task to write out a CSV format dump of all tasks, both pending
and completed, to the file specified. This is how you might view tasks in a
spreadsheet.
% task colors
-------------
This command displays all the colors that task supports.
% task usage
------------
If logging has been enabled by the "command.logging=on" directive in the
.taskrc file, then task will record every command that is run. When this
command is run, task will display a count of how many times each command was
used.
This command is for the purpose of seeing whether command are actually used.
% task version
--------------
This can be used to show the version number of task, and to display all the
current configuration settings, as read from the .taskrc file.
Interacting with the Shell
--------------------------
- Escaping shell metacharacters
Certain characters are interpreted by the shell. For example, the "&". If
you wish to include the & in a task description, you need to escape it, so
the shell doesn't interpret it. For example:
% task add Buy bread & milk
This command is an error because of the &. The shell will consider this to
be two commands:
% task add Buy bread &
% milk
The shell treats the & character as an indicator that the command is complete
and should be run in the background. Then the shell considers "milk" to be a
command all by itself. Which it is not. One way to get around this is to
individually escape the & character:
% task add Buy bread \& milk
Another is to quote the entire description, with either ' or " characters:
% task add "Buy bread & milk"
Task itself interprets the commands, and it too can make mistakes. For
example, any colon : character will be interpreted by task as a delimiter
between an attribute name and its value. Currently there is no workaround
for this.
% task <id> fg:... bg:...
-------------------------
Not strictly a command, the setting of the fg and bg (foreground and
background) attributes determines the colors used to represent the task.
Valid foreground colors are:
bold underline bold_underline
black bold_black underline_black bold_underline_black
red bold_red underline_red bold_underline_red
green bold_green underline_green bold_underline_green
yellow bold_yellow underline_yellow bold_underline_yellow
blue bold_blue underline_blue bold_underline_blue
magenta bold_magenta underline_magenta bold_underline_magenta
cyan bold_cyan underline_cyan bold_underline_cyan
white bold_white underline_white bold_underline_white
Valid background colors are:
on_black on_bright_black
on_red on_bright_red
on_green on_bright_green
on_yellow on_bright_yellow
on_blue on_bright_blue
on_magenta on_bright_magenta
on_cyan on_bright_cyan
on_white on_bright_white
Note that these are not just colors, but combinations of colors and
attributes.
Note also that this capability does depend on whether your terminal program
can display these colors.
Configuring Task
----------------
Task recognizes several entries in the .taskrc file for configuration
purposes. Valid entries are of the form:
name=value
Valid examples are:
data.location This is a path to the directory containing all the task
files. By default, it is set up to be ~/.task, for
example: /Users/paul/.task
command.logging May be "on" or "off", defaulting to "off". This
determines whether task records commands. This is not
generally useful, except while developing task.
confirmation May be "yes" or "no", and determines whether task will
ask for confirmation before deleting a task.
nag This may be a string of text, or blank. It is used as
a prompt when a task is completed that is not considered
high priority. The "task next" command lists important
tasks, and completing one of those does not generate
this nagging. Default value is:
Note: try to stick to high priority tasks.
See "task next".
next Is a number, defaulting to 2, which is the number of
tasks for each project that are shown in the "task next"
command.
curses Determines whether task uses ncurses to establish the
size of the window you are using, for text wrapping.
blanklines May be "on" or "off". Prevents the display of
unnecessary blank lines so that task makes better use
screen real estate on small-screened devices.
dateformat This is a string of characters that define how task
formats dates. The default value is:
m/d/Y
which means dates look like:
6/7/2008
The string should contain the characters:
m minimal-digit month 1, 12
d minimal-digit day 1, 30
y two-digit year 08
M two-digit month 01, 12
D two-digit day 01, 30
Y four-digit year 2008
The string may also contain other characters to act as
spacers, or formatting. Other values could include:
d/m/Y 7/6/2008
YMD 20080607
m-d-y 6-7-08
showage May be "yes" or "no". Determines whether the "Age"
column appears on the "list" and "next" reports.
color May be "on" or "off". Determines whether task uses
color.
color.overdue These are the coloration rules. They correspond to a
color.due particular attribute of a task, such as it being due, or
color.pri.H being active, and specifies the automatic coloring of
color.pri.M that task.
color.pri.L
color.pri.none The value may be one optional foreground color (see
color.active below) and one optional background color.
color.tagged
For example, the value may be:
bold_red on_bright_yellow
color.tag.X Colors any task that has the tag X.
color.project.X Colors any task assigned to project X.
color.keyword.X Colors any task where the description contains X.
Colors
------
Task supports color in several places. In cases where you may specify a
color, a foreground, a background, or a combination foreground and background
color may be used. The following are valid foreground colors:
bold underline bold_underline
black bold_black underline_black bold_underline_black
red bold_red underline_red bold_underline_red
green bold_green underline_green bold_underline_green
yellow bold_yellow underline_yellow bold_underline_yellow
blue bold_blue underline_blue bold_underline_blue
magenta bold_magenta underline_magenta bold_underline_magenta
cyan bold_cyan underline_cyan bold_underline_cyan
white bold_white underline_white bold_underline_white
and the following are valid background colors:
on_black on_bright_black
on_red on_bright_red
on_green on_bright_green
on_yellow on_bright_yellow
on_blue on_bright_blue
on_magenta on_bright_magenta
on_cyan on_bright_cyan
on_white on_bright_white

12
adsense.html Normal file
View File

@@ -0,0 +1,12 @@
<script type="text/javascript"><!--
google_ad_client = "pub-9709799404235424";
/* Task Main */
google_ad_slot = "8660617875";
google_ad_width = 120;
google_ad_height = 600;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>

36
announcement.txt Normal file
View File

@@ -0,0 +1,36 @@
Some considerable time ago - longer than I had hoped - I demonstrated an
alternate implementation of the todo script, called task, in the form of a
YouTube movie:
http://www.youtube.com/watch?v=l68LCl6BYvs
A lot has happened since then, and the task program has been slowly improving
thanks to feedback from some early testers, and continuous use by me. Today,
I have uploaded a new movie:
http://www.youtube.com/watch?v=D2Kn4DMOVSw
This movie includes most of the changes and improvements to task, but behind
the scenes are the biggest changes. There was a rewrite of the underlying
storage mechanism yielding a clean API for the front end, and the code was
reviewed for portability and converted to use GNU autoconf/automake.
Task has been released under GPL, and so far has been tested on:
Max OS X 10.4 (Tiger)
Max OS X 10.5 (Leopard)
Fedora 8
Fedora 9
Ubuntu 8 (Hardy Heron)
Solaris 10
Task has been making me more organized and productive for some time now.
Perhaps some of you might find it useful, and I welcome feedback of all kinds.
You can find the task source code at:
http://www.beckingham.net/task-1.0.0.tar.gz
Thank you.
Paul Beckingham

View File

@@ -2,11 +2,10 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.61)
AC_INIT(task, 0.9.4, bugs@beckingham.net)
AC_INIT(task, 1.2.0, bugs@beckingham.net)
AM_INIT_AUTOMAKE
AC_CONFIG_SRCDIR([src/task.cpp])
AC_CONFIG_HEADER([auto.h])
#AC_CONFIG_SUBDIRS([src])
# Checks for programs.
AC_PROG_CXX
@@ -14,12 +13,12 @@ AC_PROG_CC
AC_LANG(C++)
# Checks for libraries.
#AC_CHECK_LIB(ncurses, initscr, [LIBS="$LIBS -lncurses" AC_DEFINE([HAVE_NCURSES], [1], [Found ncurses])])
AC_CHECK_LIB(ncurses,initscr)
AC_CHECK_LIB(ncurses,endwin)
# Checks for header files.
AC_HEADER_STDC
AC_CHECK_HEADERS([stdlib.h sys/file.h sys/time.h unistd.h])
AC_CHECK_HEADERS([stdlib.h sys/file.h sys/stat.h sys/time.h unistd.h])
AC_CHECK_HEADERS([string vector map])
# Checks for typedefs, structures, and compiler characteristics.
@@ -36,6 +35,8 @@ AC_FUNC_SELECT_ARGTYPES
AC_CHECK_FUNCS([select])
AC_CHECK_FUNC(flock, [AC_DEFINE([HAVE_FLOCK], [1], [Found flock])])
AC_CHECK_FUNC(uuid_unparse_lower, [AC_DEFINE([HAVE_UUID], [1], [Found uuid_unparse_lower])])
AC_CHECK_FUNC(random, [AC_DEFINE([HAVE_RANDOM], [1], [Found random])])
AC_CHECK_FUNC(srandom, [AC_DEFINE([HAVE_SRANDOM], [1], [Found srandom])])
AC_CONFIG_FILES([Makefile])
AC_CONFIG_FILES([Makefile src/Makefile])
AC_OUTPUT

105
script.txt Normal file
View File

@@ -0,0 +1,105 @@
Hello, and welcome to this quick demo of the task program.
task add do laundry Let's add some tasks
I need to do laundry
task add project:garage order dumpster Oh yeah, the dumpster
task add +phone tell mom i loveher Must call Mom (that "phone" there is a tag - they are
useful for searching, categorizing)
task add +phone pro:garage schedule
goodwill pickup
task ad +email pro:garage ask Tom if Notice I can abbreviating commands
he wants that old bkie
task ls Let's see what we've got
I spelled bike wrong
task 5 /bkie/bike/
task ls That's better
task 1 pro:home Let's assign projects
task 3 pro:home tell mom I love her
task ls pro:garage
task long pro:garage Let's see all the columns
task list pro:garage There are different ways to list
task lis +phone By tag
task li pro:garage +phone By project and tag
task l mom By word
task 1 priority:H Priorities can be High, Medium or Low
task pri:H 3
task 1 pri:M
task li The list is sorted by priority.
task 2 pri:L
task li
task done 3 Suppose task 3 is done
task li ...and it's gone
task 2 +phone +mistake Lets add tags
# Oops!
task 2 -mistake or remove tags
task tags or look at all the tags
task info 2 or all the details
task projects or all the projects
task 3 fg:bold Let's make it colorful
task 4 fg:bold_green
task li
task 3 fg:bold_underline_white
task li
task 4 bg:on_bright_red fg:bold_yellow
task li Oh that's just nasty - let's get rid of that.
task 4 bg:
task li
task 4 fg:
task 3 fg:
task colors There are many combinations to choose from
(Slashes!!!)
task 1 due:6/8/2008 Let's add a due date
date
task li
task calendar Notice the due task is in yellow, today is marked cyan
task 1 due:5/20/2008 This is now an overdue task
task li and it shows up red
task overdue
task cal
task export file.csv You can export the tasks to a spreadsheet
cat file.csv
task start 1 Started tasks can be used as reminders
of what you are supposed to be doing
task active They show up as active
task done 1 Let's clear out a couple
task li
task done 3
task active
task summary Summary shows progress on all projects
task history History shows general activity - how many added,
completed etc, by month
And that's it. There are more commands than this
covered in the TUTORIAL file, but this should give
the basic idea.
Thank you for watching.

View File

@@ -91,14 +91,14 @@ Config.o Config.o: Config.cpp /usr/include/c++/4.0.0/iostream \
/usr/include/c++/4.0.0/bits/istream.tcc /usr/include/c++/4.0.0/fstream \
/usr/include/c++/4.0.0/i686-apple-darwin9/bits/basic_file.h \
/usr/include/c++/4.0.0/bits/fstream.tcc /usr/include/c++/4.0.0/sstream \
/usr/include/c++/4.0.0/bits/sstream.tcc task.h \
/usr/include/c++/4.0.0/bits/sstream.tcc /usr/include/sys/stat.h task.h \
/usr/include/c++/4.0.0/vector /usr/include/c++/4.0.0/bits/stl_vector.h \
/usr/include/c++/4.0.0/bits/stl_bvector.h \
/usr/include/c++/4.0.0/bits/vector.tcc /usr/include/c++/4.0.0/map \
/usr/include/c++/4.0.0/bits/stl_tree.h \
/usr/include/c++/4.0.0/bits/stl_map.h \
/usr/include/c++/4.0.0/bits/stl_multimap.h /usr/include/sys/types.h \
Config.h Table.h color.h TDB.h T.h stlmacros.h ../auto.h
Config.h Table.h color.h Grid.h color.h TDB.h T.h ../auto.h
/usr/include/c++/4.0.0/iostream:
@@ -366,6 +366,8 @@ Config.o Config.o: Config.cpp /usr/include/c++/4.0.0/iostream \
/usr/include/c++/4.0.0/bits/sstream.tcc:
/usr/include/sys/stat.h:
task.h:
/usr/include/c++/4.0.0/vector:
@@ -392,10 +394,12 @@ Table.h:
color.h:
Grid.h:
color.h:
TDB.h:
T.h:
stlmacros.h:
../auto.h:

View File

@@ -95,7 +95,7 @@ Date.o Date.o: Date.cpp /usr/include/c++/4.0.0/iostream \
/usr/include/c++/4.0.0/bits/stl_tree.h \
/usr/include/c++/4.0.0/bits/stl_map.h \
/usr/include/c++/4.0.0/bits/stl_multimap.h /usr/include/sys/types.h \
Config.h Table.h color.h TDB.h T.h stlmacros.h ../auto.h Date.h
Config.h Table.h color.h Grid.h color.h TDB.h T.h ../auto.h Date.h
/usr/include/c++/4.0.0/iostream:
@@ -379,12 +379,14 @@ Table.h:
color.h:
Grid.h:
color.h:
TDB.h:
T.h:
stlmacros.h:
../auto.h:
Date.h:

View File

@@ -95,7 +95,7 @@ T.o T.o: T.cpp /usr/include/c++/4.0.0/iostream \
/usr/include/c++/4.0.0/bits/stl_tree.h \
/usr/include/c++/4.0.0/bits/stl_map.h \
/usr/include/c++/4.0.0/bits/stl_multimap.h /usr/include/sys/types.h \
Config.h Table.h color.h TDB.h T.h stlmacros.h ../auto.h
Config.h Table.h color.h Grid.h color.h TDB.h T.h ../auto.h
/usr/include/c++/4.0.0/iostream:
@@ -379,10 +379,12 @@ Table.h:
color.h:
Grid.h:
color.h:
TDB.h:
T.h:
stlmacros.h:
../auto.h:

View File

@@ -99,7 +99,7 @@ TDB.o TDB.o: TDB.cpp /usr/include/c++/4.0.0/iostream \
/usr/include/c++/4.0.0/bits/stl_tree.h \
/usr/include/c++/4.0.0/bits/stl_map.h \
/usr/include/c++/4.0.0/bits/stl_multimap.h Config.h Table.h color.h \
TDB.h T.h stlmacros.h ../auto.h
Grid.h color.h TDB.h T.h ../auto.h
/usr/include/c++/4.0.0/iostream:
@@ -395,10 +395,12 @@ Table.h:
color.h:
Grid.h:
color.h:
TDB.h:
T.h:
stlmacros.h:
../auto.h:

View File

@@ -94,8 +94,9 @@ Table.o Table.o: Table.cpp /usr/include/c++/4.0.0/iostream \
/usr/include/c++/4.0.0/bits/stl_multimap.h \
/usr/include/c++/4.0.0/vector /usr/include/c++/4.0.0/bits/stl_vector.h \
/usr/include/c++/4.0.0/bits/stl_bvector.h \
/usr/include/c++/4.0.0/bits/vector.tcc color.h Date.h stlmacros.h \
task.h /usr/include/sys/types.h Config.h TDB.h T.h ../auto.h
/usr/include/c++/4.0.0/bits/vector.tcc color.h Grid.h Date.h task.h \
/usr/include/sys/types.h Config.h Table.h color.h TDB.h T.h T.h \
../auto.h
/usr/include/c++/4.0.0/iostream:
@@ -373,9 +374,9 @@ Table.h:
color.h:
Date.h:
Grid.h:
stlmacros.h:
Date.h:
task.h:
@@ -383,8 +384,14 @@ task.h:
Config.h:
Table.h:
color.h:
TDB.h:
T.h:
T.h:
../auto.h:

View File

@@ -95,8 +95,8 @@ parse.o parse.o: parse.cpp /usr/include/c++/4.0.0/iostream \
/usr/include/c++/4.0.0/bits/stl_tree.h \
/usr/include/c++/4.0.0/bits/stl_map.h \
/usr/include/c++/4.0.0/bits/stl_multimap.h Date.h task.h \
/usr/include/sys/types.h Config.h Table.h color.h TDB.h T.h stlmacros.h \
../auto.h
/usr/include/sys/types.h Config.h Table.h color.h Grid.h color.h TDB.h \
T.h ../auto.h
/usr/include/c++/4.0.0/iostream:
@@ -382,10 +382,12 @@ Table.h:
color.h:
Grid.h:
color.h:
TDB.h:
T.h:
stlmacros.h:
../auto.h:

View File

@@ -94,8 +94,8 @@ rules.o rules.o: rules.cpp /usr/include/c++/4.0.0/iostream \
/usr/include/c++/4.0.0/bits/stl_multimap.h \
/usr/include/c++/4.0.0/vector /usr/include/c++/4.0.0/bits/stl_vector.h \
/usr/include/c++/4.0.0/bits/stl_bvector.h \
/usr/include/c++/4.0.0/bits/vector.tcc Table.h color.h Date.h T.h \
task.h /usr/include/sys/types.h TDB.h stlmacros.h ../auto.h
/usr/include/c++/4.0.0/bits/vector.tcc Table.h color.h Grid.h Date.h \
T.h task.h /usr/include/sys/types.h color.h TDB.h ../auto.h
/usr/include/c++/4.0.0/iostream:
@@ -375,6 +375,8 @@ Table.h:
color.h:
Grid.h:
Date.h:
T.h:
@@ -383,8 +385,8 @@ task.h:
/usr/include/sys/types.h:
color.h:
TDB.h:
stlmacros.h:
../auto.h:

View File

@@ -98,8 +98,8 @@ task.o task.o: task.cpp /usr/include/c++/4.0.0/iostream \
/usr/include/c++/4.0.0/bits/stl_multimap.h \
/usr/include/c++/4.0.0/vector /usr/include/c++/4.0.0/bits/stl_vector.h \
/usr/include/c++/4.0.0/bits/stl_bvector.h \
/usr/include/c++/4.0.0/bits/vector.tcc Date.h Table.h color.h \
stlmacros.h TDB.h T.h task.h ../auto.h /usr/include/ncurses.h \
/usr/include/c++/4.0.0/bits/vector.tcc Date.h Table.h color.h Grid.h \
TDB.h T.h task.h color.h ../auto.h /usr/include/ncurses.h \
/usr/include/ncurses_dll.h /usr/include/unctrl.h /usr/include/curses.h
/usr/include/c++/4.0.0/iostream:
@@ -396,7 +396,7 @@ Table.h:
color.h:
stlmacros.h:
Grid.h:
TDB.h:
@@ -404,6 +404,8 @@ T.h:
task.h:
color.h:
../auto.h:
/usr/include/ncurses.h:

View File

@@ -95,7 +95,7 @@ text.o text.o: text.cpp /usr/include/c++/4.0.0/iostream \
/usr/include/c++/4.0.0/map /usr/include/c++/4.0.0/bits/stl_tree.h \
/usr/include/c++/4.0.0/bits/stl_map.h \
/usr/include/c++/4.0.0/bits/stl_multimap.h /usr/include/sys/types.h \
Config.h Table.h color.h TDB.h T.h stlmacros.h ../auto.h
Config.h Table.h color.h Grid.h color.h TDB.h T.h ../auto.h
/usr/include/c++/4.0.0/iostream:
@@ -379,10 +379,12 @@ Table.h:
color.h:
Grid.h:
color.h:
TDB.h:
T.h:
stlmacros.h:
../auto.h:

View File

@@ -95,8 +95,8 @@ util.o util.o: util.cpp /usr/include/c++/4.0.0/iostream \
/usr/include/sys/time.h Table.h /usr/include/c++/4.0.0/map \
/usr/include/c++/4.0.0/bits/stl_tree.h \
/usr/include/c++/4.0.0/bits/stl_map.h \
/usr/include/c++/4.0.0/bits/stl_multimap.h color.h task.h Config.h \
TDB.h T.h stlmacros.h ../auto.h /usr/include/uuid/uuid.h
/usr/include/c++/4.0.0/bits/stl_multimap.h color.h Grid.h task.h \
Config.h color.h TDB.h T.h ../auto.h /usr/include/uuid/uuid.h
/usr/include/c++/4.0.0/iostream:
@@ -378,16 +378,18 @@ Table.h:
color.h:
Grid.h:
task.h:
Config.h:
color.h:
TDB.h:
T.h:
stlmacros.h:
../auto.h:
/usr/include/uuid/uuid.h:

2
src/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
./Makefile
*.o

View File

@@ -1,11 +1,34 @@
///////////////////////////////////////////////////////////////////////////////
// Copyright 2005 - 2008, Paul Beckingham. All rights reserved.
// task - a command line task list manager.
//
// Copyright 2006 - 2008, Paul Beckingham.
// All rights reserved.
//
// This program is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free Software
// Foundation; either version 2 of the License, or (at your option) any later
// version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
// details.
//
// You should have received a copy of the GNU General Public License along with
// this program; if not, write to the
//
// Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor,
// Boston, MA
// 02110-1301
// USA
//
////////////////////////////////////////////////////////////////////////////////
#include <iostream>
#include <fstream>
#include <sstream>
#include <sys/stat.h>
#include <stdlib.h>
#include "task.h"
#include "Config.h"
@@ -34,7 +57,7 @@ bool Config::load (const std::string& file)
while (getline (in, line))
{
// Remove comments.
unsigned int pound = line.find ("#");
size_type pound = line.find ("#");
if (pound != std::string::npos)
line = line.substr (0, pound);
@@ -43,7 +66,7 @@ bool Config::load (const std::string& file)
// Skip empty lines.
if (line.length () > 0)
{
unsigned int equal = line.find ("=");
size_type equal = line.find ("=");
if (equal != std::string::npos)
{
std::string key = trim (line.substr (0, equal), " \t");
@@ -60,6 +83,72 @@ bool Config::load (const std::string& file)
return false;
}
////////////////////////////////////////////////////////////////////////////////
void Config::createDefault (const std::string& file)
{
if (confirm (
"A configuration file could not be found in "
+ file
+ "\n\n"
+ "Would you like a sample .taskrc created, so task can proceed?"))
{
// Determine a path to the task directory.
std::string taskDir = "";
for (int i = file.length () - 1; i >= 0; --i)
{
if (file[i] == '/')
{
taskDir = file.substr (0, i) + "/.task";
if (-1 == access (taskDir.c_str (), F_OK))
mkdir (taskDir.c_str (), S_IRWXU);
break;
}
}
if (taskDir != "")
{
// Create a sample .taskrc file.
FILE* out;
if ((out = fopen (file.c_str (), "w")))
{
fprintf (out, "data.location=%s\n", taskDir.c_str ());
fprintf (out, "command.logging=off\n");
fprintf (out, "confirmation=yes\n");
fprintf (out, "#nag=Note: try to stick to high priority tasks. See \"task next\".\n");
fprintf (out, "next=2\n");
fprintf (out, "curses=on\n");
fprintf (out, "color=on\n");
fprintf (out, "color.overdue=bold_red\n");
fprintf (out, "#color.due=on_bright_yellow\n");
fprintf (out, "#color.pri.H=on_red\n");
fprintf (out, "#color.pri.M=on_yellow\n");
fprintf (out, "#color.pri.L=on_green\n");
fprintf (out, "color.active=bold_cyan\n");
fprintf (out, "color.tagged=yellow\n");
fprintf (out, "#color.tag.bug=yellow\n");
fprintf (out, "#color.project.home=on_green\n");
fprintf (out, "#color.keyword.car=on_blue\n");
fclose (out);
// Now set the live values.
set ("data.location", taskDir);
set ("command.logging", "off");
set ("confirmation", "yes");
set ("next", 1);
set ("curses", "on");
set ("color", "on");
set ("color.overdue", "red");
set ("color.active", "cyan");
set ("color.tagged", "yellow");
std::cout << "Done." << std::endl;
}
}
}
}
////////////////////////////////////////////////////////////////////////////////
// Return the configuration value given the specified key.
const std::string& Config::get (const char* key)

View File

@@ -1,6 +1,27 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright 2005 - 2008, Paul Beckingham. All rights reserved.
// task - a command line task list manager.
//
// Copyright 2006 - 2008, Paul Beckingham.
// All rights reserved.
//
// This program is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free Software
// Foundation; either version 2 of the License, or (at your option) any later
// version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
// details.
//
// You should have received a copy of the GNU General Public License along with
// this program; if not, write to the
//
// Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor,
// Boston, MA
// 02110-1301
// USA
//
////////////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_CONFIG
@@ -17,6 +38,8 @@ public:
Config (const std::string&);
bool load (const std::string&);
void createDefault (const std::string&);
const std::string& get (const char*);
const std::string& get (const char*, const char*);
const std::string& get (const std::string&);

View File

@@ -1,10 +1,33 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright 2005 - 2008, Paul Beckingham. All rights reserved.
// task - a command line task list manager.
//
// Copyright 2006 - 2008, Paul Beckingham.
// All rights reserved.
//
// This program is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free Software
// Foundation; either version 2 of the License, or (at your option) any later
// version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
// details.
//
// You should have received a copy of the GNU General Public License along with
// this program; if not, write to the
//
// Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor,
// Boston, MA
// 02110-1301
// USA
//
////////////////////////////////////////////////////////////////////////////////
#include <iostream>
#include <time.h>
#include <assert.h>
#include <stdlib.h>
#include "task.h"
#include "Date.h"
@@ -34,29 +57,134 @@ Date::Date (const int m, const int d, const int y)
}
////////////////////////////////////////////////////////////////////////////////
Date::Date (const std::string& mdy)
Date::Date (const std::string& mdy, const std::string format /* = "m/d/Y" */)
{
unsigned int firstSlash = mdy.find ("/");
unsigned int secondSlash = mdy.find ("/", firstSlash + 1);
if (firstSlash != std::string::npos &&
secondSlash != std::string::npos)
{
int m = ::atoi (mdy.substr (0, firstSlash ).c_str ());
int d = ::atoi (mdy.substr (firstSlash + 1, secondSlash - firstSlash).c_str ());
int y = ::atoi (mdy.substr (secondSlash + 1, std::string::npos ).c_str ());
if (!valid (m, d, y))
throw std::string ("\"") + mdy + "\" is not a valid date.";
int month = 0;
int day = 0;
int year = 0;
// Duplicate Date::Date (const int, const int, const int);
struct tm t = {0};
t.tm_mday = d;
t.tm_mon = m - 1;
t.tm_year = y - 1900;
unsigned int i = 0; // Index into mdy.
for (unsigned int f = 0; f < format.length (); ++f)
{
switch (format[f])
{
// Single or double digit.
case 'm':
if (i >= mdy.length () ||
! ::isdigit (mdy[i]))
{
throw std::string ("\"") + mdy + "\" is not a valid date.";
}
if (i + 1 < mdy.length () &&
mdy[i + 0] == '1' &&
(mdy[i + 1] == '0' || mdy[i + 1] == '1' || mdy[i + 1] == '2'))
{
month = ::atoi (mdy.substr (i, 2).c_str ());
i += 2;
}
else
{
month = ::atoi (mdy.substr (i, 1).c_str ());
++i;
}
break;
case 'd':
if (i >= mdy.length () ||
! ::isdigit (mdy[i]))
{
throw std::string ("\"") + mdy + "\" is not a valid date.";
}
if (i + 1 < mdy.length () &&
(mdy[i + 0] == '1' || mdy[i + 0] == '2' || mdy[i + 0] == '3') &&
::isdigit (mdy[i + 1]))
{
day = ::atoi (mdy.substr (i, 2).c_str ());
i += 2;
}
else
{
day = ::atoi (mdy.substr (i, 1).c_str ());
++i;
}
break;
// Double digit.
case 'y':
if (i + 1 >= mdy.length () ||
! ::isdigit (mdy[i + 0]) ||
! ::isdigit (mdy[i + 1]))
{
throw std::string ("\"") + mdy + "\" is not a valid date.";
}
year = ::atoi (mdy.substr (i, 2).c_str ()) + 2000;
i += 2;
break;
case 'M':
if (i + 1 >= mdy.length () ||
! ::isdigit (mdy[i + 0]) ||
! ::isdigit (mdy[i + 1]))
{
throw std::string ("\"") + mdy + "\" is not a valid date.";
}
month = ::atoi (mdy.substr (i, 2).c_str ());
i += 2;
break;
case 'D':
if (i + 1 >= mdy.length () ||
! ::isdigit (mdy[i + 0]) ||
! ::isdigit (mdy[i + 1]))
{
throw std::string ("\"") + mdy + "\" is not a valid date.";
}
day = ::atoi (mdy.substr (i, 2).c_str ());
i += 2;
break;
// Quadruple digit.
case 'Y':
if (i + 3 >= mdy.length () ||
! ::isdigit (mdy[i + 0]) ||
! ::isdigit (mdy[i + 1]) ||
! ::isdigit (mdy[i + 2]) ||
! ::isdigit (mdy[i + 3]))
{
throw std::string ("\"") + mdy + "\" is not a valid date.";
}
year = ::atoi (mdy.substr (i, 4).c_str ());
i += 4;
break;
default:
if (i >= mdy.length () ||
mdy[i] != format[f])
{
throw std::string ("\"") + mdy + "\" is not a valid date.";
}
++i;
break;
}
}
if (!valid (month, day, year))
throw std::string ("\"") + mdy + "\" is not a valid date.";
// Duplicate Date::Date (const int, const int, const int);
struct tm t = {0};
t.tm_mday = day;
t.tm_mon = month - 1;
t.tm_year = year - 1900;
mT = mktime (&t);
}
else
throw std::string ("\"") + mdy + "\" is not a valid date.";
}
////////////////////////////////////////////////////////////////////////////////
@@ -93,20 +221,68 @@ void Date::toMDY (int& m, int& d, int& y)
}
////////////////////////////////////////////////////////////////////////////////
void Date::toString (std::string& output)
std::string Date::toString (const std::string& format /*= "m/d/Y"*/)
{
output = toString ();
}
std::string formatted;
for (unsigned int i = 0; i < format.length (); ++i)
{
switch (format[i])
{
case 'm':
{
char m[3];
sprintf (m, "%d", this->month ());
formatted += m;
}
break;
////////////////////////////////////////////////////////////////////////////////
std::string Date::toString (void)
{
int m, d, y;
toMDY (m, d, y);
case 'M':
{
char m[3];
sprintf (m, "%02d", this->month ());
formatted += m;
}
break;
char formatted [11];
sprintf (formatted, "%d/%d/%d", m, d, y);
return std::string (formatted);
case 'd':
{
char d[3];
sprintf (d, "%d", this->day ());
formatted += d;
}
break;
case 'D':
{
char d[3];
sprintf (d, "%02d", this->day ());
formatted += d;
}
break;
case 'y':
{
char y[3];
sprintf (y, "%02d", this->year () % 100);
formatted += y;
}
break;
case 'Y':
{
char y[5];
sprintf (y, "%d", this->year ());
formatted += y;
}
break;
default:
formatted += format[i];
break;
}
}
return formatted;
}
////////////////////////////////////////////////////////////////////////////////
@@ -155,7 +331,7 @@ int Date::daysInMonth (int month, int year)
////////////////////////////////////////////////////////////////////////////////
std::string Date::monthName (int month)
{
static char* months[12] =
static const char* months[12] =
{
"January",
"February",
@@ -179,7 +355,7 @@ std::string Date::monthName (int month)
////////////////////////////////////////////////////////////////////////////////
void Date::dayName (int dow, std::string& name)
{
static char* days[7] =
static const char* days[7] =
{
"Sunday",
"Monday",
@@ -196,7 +372,7 @@ void Date::dayName (int dow, std::string& name)
////////////////////////////////////////////////////////////////////////////////
std::string Date::dayName (int dow)
{
static char* days[7] =
static const char* days[7] =
{
"Sunday",
"Monday",
@@ -211,28 +387,28 @@ std::string Date::dayName (int dow)
}
////////////////////////////////////////////////////////////////////////////////
int Date::dayOfWeek ()
int Date::dayOfWeek () const
{
struct tm* t = localtime (&mT);
return t->tm_wday;
}
////////////////////////////////////////////////////////////////////////////////
int Date::month ()
int Date::month () const
{
struct tm* t = localtime (&mT);
return t->tm_mon + 1;
}
////////////////////////////////////////////////////////////////////////////////
int Date::day ()
int Date::day () const
{
struct tm* t = localtime (&mT);
return t->tm_mday;
}
////////////////////////////////////////////////////////////////////////////////
int Date::year ()
int Date::year () const
{
struct tm* t = localtime (&mT);
return t->tm_year + 1900;

View File

@@ -1,6 +1,27 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright 2005 - 2008, Paul Beckingham. All rights reserved.
// task - a command line task list manager.
//
// Copyright 2006 - 2008, Paul Beckingham.
// All rights reserved.
//
// This program is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free Software
// Foundation; either version 2 of the License, or (at your option) any later
// version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
// details.
//
// You should have received a copy of the GNU General Public License along with
// this program; if not, write to the
//
// Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor,
// Boston, MA
// 02110-1301
// USA
//
////////////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_DATE
@@ -16,15 +37,14 @@ public:
Date ();
Date (time_t);
Date (const int, const int, const int);
Date (const std::string&);
Date (const std::string&, const std::string format = "m/d/Y");
Date (const Date&);
virtual ~Date ();
void toEpoch (time_t&);
time_t toEpoch ();
void toMDY (int&, int&, int&);
void toString (std::string&);
std::string toString (void);
std::string toString (const std::string& format = "m/d/Y");
static bool valid (const int, const int, const int);
static bool leapYear (int);
@@ -32,11 +52,11 @@ public:
static std::string monthName (int);
static void dayName (int, std::string&);
static std::string dayName (int);
int dayOfWeek ();
int dayOfWeek () const;
int month ();
int day ();
int year ();
int month () const;
int day () const;
int year () const;
bool operator== (const Date&);
bool operator!= (const Date&);

425
src/Grid.cpp Normal file
View File

@@ -0,0 +1,425 @@
////////////////////////////////////////////////////////////////////////////////
// task - a command line task list manager.
//
// Copyright 2006 - 2008, Paul Beckingham.
// All rights reserved.
//
// This program is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free Software
// Foundation; either version 2 of the License, or (at your option) any later
// version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
// details.
//
// You should have received a copy of the GNU General Public License along with
// this program; if not, write to the
//
// Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor,
// Boston, MA
// 02110-1301
// USA
//
//
//
// Grid implements a sparse 2D array of Cell objects. Grid makes every effort
// to perform well on cell insertion and retrieval. A Cell is a variant type,
// capable of storing char, bool, int, float, double and std::string types.
//
// Every cell is accessible from both mColumns and mRows. This allows the
// client code to specify which method is used, because there will be a
// performance penalty with one of the methods, depending on the layout of
// cells within the grid.
//
// mColumns, like mRows, is a vector of a vector of Cell*.
//
// mColumns
// [0..n]
// +---+---+-----------+---+
// | 0 | 1 | | n |
// +---+---+-----------+---+
// | |
// v |
// +---+ . +---+ . | .
// mRows | 0 | -------> | x | v
// [0..1] +---+ . +---+ +---+
// | 1 | -------> | y | --------> | z |
// +---+ . +---+ +---+
// | |
// | |
// | |
// +---+ . . . . .
// | n |
// +---+ . . . . .
//
//
//
////////////////////////////////////////////////////////////////////////////////
#include <iostream>
#include <Grid.h>
////////////////////////////////////////////////////////////////////////////////
Grid::Grid ()
{
}
////////////////////////////////////////////////////////////////////////////////
// The cells are deleted via their mRows reference, not by their mColumns
// reference. This is because the cells are doubly-linked, and so the
// convention is that rows own cells, columns merely own pointers.
Grid::~Grid ()
{
std::vector < std::vector <Cell*>* >::iterator row;
std::vector <Cell*>::iterator col;
for (row = mRows.begin (); row != mRows.end (); ++row)
if (*row)
for (col = (*row)->begin (); col != (*row)->end (); ++col)
if (*col)
delete *col;
std::vector < std::vector <Cell*>* >::iterator it;
for (it = mRows.begin (); it != mRows.end (); ++it)
if (*it)
delete *it;
for (it = mColumns.begin (); it != mColumns.end (); ++it)
if (*it)
delete *it;
}
////////////////////////////////////////////////////////////////////////////////
void Grid::add (
const unsigned int row,
const unsigned int col,
const bool value)
{
expandGrid (row, col);
insertCell (row, col, new Cell (value));
}
void Grid::add (
const unsigned int row,
const unsigned int col,
const char value)
{
expandGrid (row, col);
insertCell (row, col, new Cell (value));
}
void Grid::add (
const unsigned int row,
const unsigned int col,
const int value)
{
expandGrid (row, col);
insertCell (row, col, new Cell (value));
}
void Grid::add (
const unsigned int row,
const unsigned int col,
const float value)
{
expandGrid (row, col);
insertCell (row, col, new Cell (value));
}
void Grid::add (
const unsigned int row,
const unsigned int col,
const double value)
{
expandGrid (row, col);
insertCell (row, col, new Cell (value));
}
void Grid::add (
const unsigned int row,
const unsigned int col,
const char* value)
{
expandGrid (row, col);
insertCell (row, col, new Cell (std::string (value)));
}
void Grid::add (
const unsigned int row,
const unsigned int col,
const std::string& value)
{
expandGrid (row, col);
insertCell (row, col, new Cell (value));
}
////////////////////////////////////////////////////////////////////////////////
unsigned int Grid::width () const
{
return mColumns.size ();
}
unsigned int Grid::height () const
{
return mRows.size ();
}
////////////////////////////////////////////////////////////////////////////////
Grid::Cell* Grid::byRow (const unsigned int row, const unsigned int col) const
{
if (row < mRows.size () &&
mRows[row] != NULL &&
col < mRows[row]->size ())
return (*mRows[row])[col];
return NULL;
}
Grid::Cell* Grid::byColumn (const unsigned int row, const unsigned int col) const
{
if (col < mColumns.size () &&
mColumns[col] != NULL &&
row < mColumns[col]->size ())
return (*mColumns[col])[row];
return NULL;
}
////////////////////////////////////////////////////////////////////////////////
void Grid::expandGrid (const unsigned int row, const unsigned int col)
{
// If the new row is outside the bounds of the current grid, add blank rows to
// pad, then a new row vector.
if (row >= mRows.size ())
{
for (unsigned int r = mRows.size (); r <= row; ++r)
if (r < row)
mRows.push_back (NULL);
else
mRows.push_back (new std::vector <Cell*>);
}
// If the new row is within the bounds of the current grid, ensure that the
// row points to a vector of cells.
else if (mRows[row] == NULL)
mRows[row] = new std::vector <Cell*>;
if (col >= mRows[row]->size ())
for (unsigned int c = mRows[row]->size (); c <= col; ++c)
mRows[row]->push_back (NULL);
// If the new col is outside the bounds of the current grid, add blank cols to
// pad, then a new col vector.
if (col >= mColumns.size ())
{
for (unsigned int c = mColumns.size (); c <= col; ++c)
if (c < col)
mColumns.push_back (NULL);
else
mColumns.push_back (new std::vector <Cell*>);
}
// If the new col is within the bounds of the current grid, ensure that the
// col points to a vector of cells.
else if (mColumns[col] == NULL)
mColumns[col] = new std::vector <Cell*>;
if (row >= mColumns[col]->size ())
for (unsigned int r = mColumns[col]->size (); r <= row; ++r)
mColumns[col]->push_back (NULL);
}
////////////////////////////////////////////////////////////////////////////////
void Grid::insertCell (
const unsigned int row,
const unsigned int col,
Cell* cell)
{
// Delete any existing cell, because cells are owned by rows, not columns.
if ((*mRows[row])[col] != NULL)
delete (*mRows[row])[col];
(*mRows[row])[col] = cell;
(*mColumns[col])[row] = cell;
}
////////////////////////////////////////////////////////////////////////////////
Grid::Cell::Cell (const bool value)
: mType (CELL_BOOL)
, mBool (value)
{
}
Grid::Cell::Cell (const char value)
: mType (CELL_CHAR)
, mChar (value)
{
}
Grid::Cell::Cell (const int value)
: mType (CELL_INT)
, mInt (value)
{
}
Grid::Cell::Cell (const float value)
: mType (CELL_FLOAT)
, mFloat (value)
{
}
Grid::Cell::Cell (const double value)
: mType (CELL_DOUBLE)
, mDouble (value)
{
}
Grid::Cell::Cell (const std::string& value)
: mType (CELL_STRING)
, mString (value)
{
}
////////////////////////////////////////////////////////////////////////////////
// These cast operators make a best approximation to an appropriate rendering,
// given the format change.
Grid::Cell::operator bool () const
{
switch (mType)
{
case CELL_BOOL: return mBool;
case CELL_CHAR: return mChar != '\0' &&
mChar != ' ' &&
mChar != '0';
case CELL_INT: return mInt != 0;
case CELL_FLOAT: return mFloat != 0.0;
case CELL_DOUBLE: return mDouble != 0.0;
case CELL_STRING: return mString.length () > 0;
}
return false;
}
Grid::Cell::operator char () const
{
switch (mType)
{
case CELL_BOOL: return mBool ? 'Y' : 'N';
case CELL_CHAR: return mChar;
case CELL_INT: return (char) mInt;
case CELL_FLOAT: return (char) (int) mFloat;
case CELL_DOUBLE: return (char) (int) mDouble;
case CELL_STRING: return mString[0];
}
return '\0';
}
Grid::Cell::operator int () const
{
switch (mType)
{
case CELL_BOOL: return mBool ? 1 : 0;
case CELL_CHAR: return (int) mChar;
case CELL_INT: return mInt;
case CELL_FLOAT: return (int) mFloat;
case CELL_DOUBLE: return (int) mDouble;
case CELL_STRING: return mString.length ();
}
return 0;
}
Grid::Cell::operator float () const
{
switch (mType)
{
case CELL_BOOL: return mBool ? 1.0 : 0.0;
case CELL_CHAR: return (float) (int) mChar;
case CELL_INT: return (float) mInt;
case CELL_FLOAT: return mFloat;
case CELL_DOUBLE: return (float) mDouble;
case CELL_STRING: return (float) mString.length ();
}
return 0.0;
}
Grid::Cell::operator double () const
{
switch (mType)
{
case CELL_BOOL: return mBool ? 1.0 : 0.0;
case CELL_CHAR: return (double) (int) mChar;
case CELL_INT: return (double) mInt;
case CELL_FLOAT: return (double) mFloat;
case CELL_DOUBLE: return mDouble;
case CELL_STRING: return (double) mString.length ();
}
return 0.0;
}
Grid::Cell::operator std::string () const
{
char s[64] = {0};
switch (mType)
{
case CELL_BOOL: return mBool ? "true" : "false";
case CELL_CHAR: sprintf (s, "%c", mChar);
return std::string (s);
case CELL_INT: sprintf (s, "%d", mInt);
return std::string (s);
case CELL_FLOAT: sprintf (s, "%f", mFloat);
return std::string (s);
case CELL_DOUBLE: sprintf (s, "%f", mDouble);
return std::string (s);
case CELL_STRING: return mString;
}
return std::string ("");
}
////////////////////////////////////////////////////////////////////////////////
bool Grid::Cell::operator== (const Grid::Cell& rhs) const
{
switch (mType)
{
case CELL_BOOL: return mBool == rhs.mBool ? true : false;
case CELL_CHAR: return mChar == rhs.mChar ? true : false;
case CELL_INT: return mInt == rhs.mInt ? true : false;
case CELL_FLOAT: return mFloat == rhs.mFloat ? true : false;
case CELL_DOUBLE: return mDouble == rhs.mDouble ? true : false;
case CELL_STRING: return mString == rhs.mString ? true : false;
default: break; // To prevent warnings.
}
return false;
}
////////////////////////////////////////////////////////////////////////////////
bool Grid::Cell::operator!= (const Grid::Cell& rhs) const
{
switch (mType)
{
case CELL_BOOL: return mBool != rhs.mBool ? true : false;
case CELL_CHAR: return mChar != rhs.mChar ? true : false;
case CELL_INT: return mInt != rhs.mInt ? true : false;
case CELL_FLOAT: return mFloat != rhs.mFloat ? true : false;
case CELL_DOUBLE: return mDouble != rhs.mDouble ? true : false;
case CELL_STRING: return mString != rhs.mString ? true : false;
default: break; // To prevent warnings.
}
return false;
}
////////////////////////////////////////////////////////////////////////////////
Grid::Cell::cellType Grid::Cell::type () const
{
return mType;
}
////////////////////////////////////////////////////////////////////////////////

99
src/Grid.h Normal file
View File

@@ -0,0 +1,99 @@
////////////////////////////////////////////////////////////////////////////////
// task - a command line task list manager.
//
// Copyright 2006 - 2008, Paul Beckingham.
// All rights reserved.
//
// This program is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free Software
// Foundation; either version 2 of the License, or (at your option) any later
// version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
// details.
//
// You should have received a copy of the GNU General Public License along with
// this program; if not, write to the
//
// Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor,
// Boston, MA
// 02110-1301
// USA
//
////////////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_GRID
#define INCLUDED_GRID
#include <string>
#include <vector>
////////////////////////////////////////////////////////////////////////////////
class Grid
{
public:
class Cell
{
public:
Cell (const bool);
Cell (const char);
Cell (const int);
Cell (const float);
Cell (const double);
Cell (const std::string&);
operator bool () const;
operator char () const;
operator int () const;
operator float () const;
operator double () const;
operator std::string () const;
bool operator== (const Cell&) const;
bool operator!= (const Cell&) const;
enum cellType {CELL_BOOL, CELL_CHAR, CELL_INT, CELL_FLOAT, CELL_DOUBLE, CELL_STRING};
cellType type () const;
private:
cellType mType;
bool mBool;
char mChar;
int mInt;
float mFloat;
double mDouble;
std::string mString;
};
public:
Grid ();
~Grid ();
void add (const unsigned int, const unsigned int, const bool);
void add (const unsigned int, const unsigned int, const char);
void add (const unsigned int, const unsigned int, const int);
void add (const unsigned int, const unsigned int, const float);
void add (const unsigned int, const unsigned int, const double);
void add (const unsigned int, const unsigned int, const char*);
void add (const unsigned int, const unsigned int, const std::string&);
unsigned int width () const;
unsigned int height () const;
Cell* byRow (const unsigned int, const unsigned int) const;
Cell* byColumn (const unsigned int, const unsigned int) const;
private:
void expandGrid (const unsigned int, const unsigned int);
void insertCell (const unsigned int, const unsigned int, Cell*);
private:
std::vector < std::vector <Cell*>* > mRows;
std::vector < std::vector <Cell*>* > mColumns;
};
#endif
////////////////////////////////////////////////////////////////////////////////

View File

@@ -1,429 +0,0 @@
# Makefile.in generated by automake 1.10 from Makefile.am.
# src/Makefile. Generated from Makefile.in by configure.
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
pkgdatadir = $(datadir)/task
pkglibdir = $(libdir)/task
pkgincludedir = $(includedir)/task
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
bin_PROGRAMS = task$(EXEEXT)
subdir = src
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/auto.h
CONFIG_CLEAN_FILES =
am__installdirs = "$(DESTDIR)$(bindir)"
binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
PROGRAMS = $(bin_PROGRAMS)
am_task_OBJECTS = Config.$(OBJEXT) Date.$(OBJEXT) T.$(OBJEXT) \
TDB.$(OBJEXT) Table.$(OBJEXT) color.$(OBJEXT) parse.$(OBJEXT) \
task.$(OBJEXT) util.$(OBJEXT) text.$(OBJEXT) rules.$(OBJEXT)
task_OBJECTS = $(am_task_OBJECTS)
task_LDADD = $(LDADD)
DEFAULT_INCLUDES = -I. -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
CXXLD = $(CXX)
CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
-o $@
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
SOURCES = $(task_SOURCES)
DIST_SOURCES = $(task_SOURCES)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = ${SHELL} /Users/paul/work/task_rel/missing --run aclocal-1.10
AMTAR = ${SHELL} /Users/paul/work/task_rel/missing --run tar
AUTOCONF = ${SHELL} /Users/paul/work/task_rel/missing --run autoconf
AUTOHEADER = ${SHELL} /Users/paul/work/task_rel/missing --run autoheader
AUTOMAKE = ${SHELL} /Users/paul/work/task_rel/missing --run automake-1.10
AWK = awk
CC = gcc
CCDEPMODE = depmode=gcc3
CFLAGS = -g -O2
CPPFLAGS =
CXX = g++
CXXCPP = g++ -E
CXXDEPMODE = depmode=gcc3
CXXFLAGS = -g -O2
CYGPATH_W = echo
DEFS = -DHAVE_CONFIG_H
DEPDIR = .deps
ECHO_C = \c
ECHO_N =
ECHO_T =
EGREP = /usr/bin/grep -E
EXEEXT =
GREP = /usr/bin/grep
INSTALL = /usr/bin/install -c
INSTALL_DATA = ${INSTALL} -m 644
INSTALL_PROGRAM = ${INSTALL}
INSTALL_SCRIPT = ${INSTALL}
INSTALL_STRIP_PROGRAM = $(install_sh) -c -s
LDFLAGS =
LIBOBJS = ${LIBOBJDIR}mktime$U.o
LIBS = -lncurses
LTLIBOBJS = ${LIBOBJDIR}mktime$U.lo
MAKEINFO = ${SHELL} /Users/paul/work/task_rel/missing --run makeinfo
MKDIR_P = .././install-sh -c -d
OBJEXT = o
PACKAGE = task
PACKAGE_BUGREPORT = bugs@beckingham.net
PACKAGE_NAME = task
PACKAGE_STRING = task 0.9.0
PACKAGE_TARNAME = task
PACKAGE_VERSION = 0.9.0
PATH_SEPARATOR = :
SET_MAKE =
SHELL = /bin/sh
STRIP =
VERSION = 0.9.0
abs_builddir = /Users/paul/work/task_rel/src
abs_srcdir = /Users/paul/work/task_rel/src
abs_top_builddir = /Users/paul/work/task_rel
abs_top_srcdir = /Users/paul/work/task_rel
ac_ct_CC = gcc
ac_ct_CXX = g++
am__include = include
am__leading_dot = .
am__quote =
am__tar = ${AMTAR} chof - "$$tardir"
am__untar = ${AMTAR} xf -
bindir = ${exec_prefix}/bin
build_alias =
builddir = .
datadir = ${datarootdir}
datarootdir = ${prefix}/share
docdir = ${datarootdir}/doc/${PACKAGE_TARNAME}
dvidir = ${docdir}
exec_prefix = ${prefix}
host_alias =
htmldir = ${docdir}
includedir = ${prefix}/include
infodir = ${datarootdir}/info
install_sh = $(SHELL) /Users/paul/work/task_rel/install-sh
libdir = ${exec_prefix}/lib
libexecdir = ${exec_prefix}/libexec
localedir = ${datarootdir}/locale
localstatedir = ${prefix}/var
mandir = ${datarootdir}/man
mkdir_p = $(top_builddir)/./install-sh -c -d
oldincludedir = /usr/include
pdfdir = ${docdir}
prefix = /usr/local
program_transform_name = s,x,x,
psdir = ${docdir}
sbindir = ${exec_prefix}/sbin
sharedstatedir = ${prefix}/com
srcdir = .
subdirs = src
sysconfdir = ${prefix}/etc
target_alias =
top_builddir = ..
top_srcdir = ..
task_SOURCES = Config.cpp Date.cpp T.cpp TDB.cpp Table.cpp color.cpp parse.cpp task.cpp util.cpp text.cpp rules.cpp Config.h Date.h T.h TDB.h Table.h color.h stlmacros.h task.h
all: all-am
.SUFFIXES:
.SUFFIXES: .cpp .o .obj
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu src/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
install-binPROGRAMS: $(bin_PROGRAMS)
@$(NORMAL_INSTALL)
test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
@list='$(bin_PROGRAMS)'; for p in $$list; do \
p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
if test -f $$p \
; then \
f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
echo " $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \
$(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \
else :; fi; \
done
uninstall-binPROGRAMS:
@$(NORMAL_UNINSTALL)
@list='$(bin_PROGRAMS)'; for p in $$list; do \
f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \
rm -f "$(DESTDIR)$(bindir)/$$f"; \
done
clean-binPROGRAMS:
-test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
task$(EXEEXT): $(task_OBJECTS) $(task_DEPENDENCIES)
@rm -f task$(EXEEXT)
$(CXXLINK) $(task_OBJECTS) $(task_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
include ./$(DEPDIR)/Config.Po
include ./$(DEPDIR)/Date.Po
include ./$(DEPDIR)/T.Po
include ./$(DEPDIR)/TDB.Po
include ./$(DEPDIR)/Table.Po
include ./$(DEPDIR)/color.Po
include ./$(DEPDIR)/parse.Po
include ./$(DEPDIR)/rules.Po
include ./$(DEPDIR)/task.Po
include ./$(DEPDIR)/text.Po
include ./$(DEPDIR)/util.Po
.cpp.o:
$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
# source='$<' object='$@' libtool=no \
# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
# $(CXXCOMPILE) -c -o $@ $<
.cpp.obj:
$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
# source='$<' object='$@' libtool=no \
# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
# $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(PROGRAMS)
installdirs:
for dir in "$(DESTDIR)$(bindir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-binPROGRAMS clean-generic mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
info: info-am
info-am:
install-data-am:
install-dvi: install-dvi-am
install-exec-am: install-binPROGRAMS
install-html: install-html-am
install-info: install-info-am
install-man:
install-pdf: install-pdf-am
install-ps: install-ps-am
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-binPROGRAMS
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \
clean-generic ctags distclean distclean-compile \
distclean-generic distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-binPROGRAMS \
install-data install-data-am install-dvi install-dvi-am \
install-exec install-exec-am install-html install-html-am \
install-info install-info-am install-man install-pdf \
install-pdf-am install-ps install-ps-am install-strip \
installcheck installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \
uninstall-am uninstall-binPROGRAMS
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View File

@@ -1,2 +1,3 @@
bin_PROGRAMS = task
task_SOURCES = Config.cpp Date.cpp T.cpp TDB.cpp Table.cpp color.cpp parse.cpp task.cpp util.cpp text.cpp rules.cpp Config.h Date.h T.h TDB.h Table.h color.h stlmacros.h task.h
task_SOURCES = Config.cpp Date.cpp T.cpp TDB.cpp Table.cpp Grid.cpp color.cpp parse.cpp task.cpp util.cpp text.cpp rules.cpp Config.h Date.h T.h TDB.h Table.h Grid.h color.h task.h
AM_CPPFLAGS = -Wall -pedantic -ggdb3 -fno-rtti

View File

@@ -44,8 +44,9 @@ am__installdirs = "$(DESTDIR)$(bindir)"
binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
PROGRAMS = $(bin_PROGRAMS)
am_task_OBJECTS = Config.$(OBJEXT) Date.$(OBJEXT) T.$(OBJEXT) \
TDB.$(OBJEXT) Table.$(OBJEXT) color.$(OBJEXT) parse.$(OBJEXT) \
task.$(OBJEXT) util.$(OBJEXT) text.$(OBJEXT) rules.$(OBJEXT)
TDB.$(OBJEXT) Table.$(OBJEXT) Grid.$(OBJEXT) color.$(OBJEXT) \
parse.$(OBJEXT) task.$(OBJEXT) util.$(OBJEXT) text.$(OBJEXT) \
rules.$(OBJEXT)
task_OBJECTS = $(am_task_OBJECTS)
task_LDADD = $(LDADD)
DEFAULT_INCLUDES = -I. -I$(top_builddir)@am__isrc@
@@ -149,12 +150,12 @@ psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
subdirs = @subdirs@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
task_SOURCES = Config.cpp Date.cpp T.cpp TDB.cpp Table.cpp color.cpp parse.cpp task.cpp util.cpp text.cpp rules.cpp Config.h Date.h T.h TDB.h Table.h color.h stlmacros.h task.h
task_SOURCES = Config.cpp Date.cpp T.cpp TDB.cpp Table.cpp Grid.cpp color.cpp parse.cpp task.cpp util.cpp text.cpp rules.cpp Config.h Date.h T.h TDB.h Table.h Grid.h color.h task.h
AM_CPPFLAGS = -Wall -pedantic -ggdb3 -fno-rtti
all: all-am
.SUFFIXES:
@@ -223,6 +224,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Config.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Date.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Grid.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/T.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TDB.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Table.Po@am__quote@

View File

@@ -1,6 +1,27 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright 2006 - 2008, Paul Beckingham. All rights reserved.
// task - a command line task list manager.
//
// Copyright 2006 - 2008, Paul Beckingham.
// All rights reserved.
//
// This program is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free Software
// Foundation; either version 2 of the License, or (at your option) any later
// version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
// details.
//
// You should have received a copy of the GNU General Public License along with
// this program; if not, write to the
//
// Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor,
// Boston, MA
// 02110-1301
// USA
//
////////////////////////////////////////////////////////////////////////////////
#include <iostream>
@@ -115,7 +136,7 @@ void T::addTag (const std::string& tag)
////////////////////////////////////////////////////////////////////////////////
void T::addTags (const std::vector <std::string>& tags)
{
for (unsigned int i = 0; i < tags.size (); ++i)
for (size_t i = 0; i < tags.size (); ++i)
{
if (tags[i].find (' ') != std::string::npos)
throw std::string ("T::addTags - tags may not contain spaces");
@@ -137,7 +158,7 @@ void T::addTags (const std::vector <std::string>& tags)
void T::removeTag (const std::string& tag)
{
std::vector <std::string> copy;
for (unsigned int i = 0; i < mTags.size (); ++i)
for (size_t i = 0; i < mTags.size (); ++i)
if (mTags[i] != tag)
copy.push_back (mTags[i]);
@@ -242,7 +263,7 @@ const std::string T::compose () const
else if (mStatus == deleted) line += "X [";
// Tags
for (unsigned int i = 0; i < mTags.size (); ++i)
for (size_t i = 0; i < mTags.size (); ++i)
{
line += (i > 0 ? " " : "");
line += mTags[i];
@@ -254,20 +275,8 @@ const std::string T::compose () const
int count = 0;
foreach (i, mAttributes)
{
std::string converted = i->second;
// Date attributes may need conversion to epoch.
if (i->first == "due" ||
i->first == "start" ||
i->first == "entry" ||
i->first == "end")
{
if (i->second.find ("/") != std::string::npos)
validDate (converted);
}
line += (count > 0 ? " " : "");
line += i->first + ":" + converted;
line += i->first + ":" + i->second;
++count;
}
@@ -297,7 +306,7 @@ const std::string T::composeCSV ()
// Tags
line += "'";
for (unsigned int i = 0; i < mTags.size (); ++i)
for (size_t i = 0; i < mTags.size (); ++i)
{
line += (i > 0 ? " " : "");
line += mTags[i];
@@ -364,13 +373,13 @@ void T::parse (const std::string& line)
if (line[0] == 'X')
setStatus (deleted);
unsigned int openTagBracket = line.find ("[");
unsigned int closeTagBracket = line.find ("]", openTagBracket);
size_t openTagBracket = line.find ("[");
size_t closeTagBracket = line.find ("]", openTagBracket);
if (openTagBracket != std::string::npos &&
closeTagBracket != std::string::npos)
{
unsigned int openAttrBracket = line.find ("[", closeTagBracket);
unsigned int closeAttrBracket = line.find ("]", openAttrBracket);
size_t openAttrBracket = line.find ("[", closeTagBracket);
size_t closeAttrBracket = line.find ("]", openAttrBracket);
if (openAttrBracket != std::string::npos &&
closeAttrBracket != std::string::npos)
{
@@ -383,7 +392,7 @@ void T::parse (const std::string& line)
openAttrBracket + 1, closeAttrBracket - openAttrBracket - 1);
std::vector <std::string> pairs;
split (pairs, attributes, ' ');
for (unsigned int i = 0; i < pairs.size (); ++i)
for (size_t i = 0; i < pairs.size (); ++i)
{
std::vector <std::string> pair;
split (pair, pairs[i], ':');
@@ -415,13 +424,13 @@ void T::parse (const std::string& line)
: line[37] == 'X' ? deleted
: pending;
unsigned int openTagBracket = line.find ("[");
unsigned int closeTagBracket = line.find ("]", openTagBracket);
size_t openTagBracket = line.find ("[");
size_t closeTagBracket = line.find ("]", openTagBracket);
if (openTagBracket != std::string::npos &&
closeTagBracket != std::string::npos)
{
unsigned int openAttrBracket = line.find ("[", closeTagBracket);
unsigned int closeAttrBracket = line.find ("]", openAttrBracket);
size_t openAttrBracket = line.find ("[", closeTagBracket);
size_t closeAttrBracket = line.find ("]", openAttrBracket);
if (openAttrBracket != std::string::npos &&
closeAttrBracket != std::string::npos)
{
@@ -434,7 +443,7 @@ void T::parse (const std::string& line)
openAttrBracket + 1, closeAttrBracket - openAttrBracket - 1);
std::vector <std::string> pairs;
split (pairs, attributes, ' ');
for (unsigned int i = 0; i < pairs.size (); ++i)
for (size_t i = 0; i < pairs.size (); ++i)
{
std::vector <std::string> pair;
split (pair, pairs[i], ':');
@@ -500,7 +509,7 @@ int T::determineVersion (const std::string& line)
// a UUID followed by a status, then there is still a way to differentiate
// between 2 and 3.
//
// The danger is that a version 2 binary reads and misinterprets a version 2
// The danger is that a version 2 binary reads and misinterprets a version 3
// file. This is why it is a good idea to rely on an explicit version
// declaration rather than chance positioning.
@@ -508,3 +517,4 @@ int T::determineVersion (const std::string& line)
return 0;
}
////////////////////////////////////////////////////////////////////////////////

23
src/T.h
View File

@@ -1,6 +1,27 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright 2006 - 2007, Paul Beckingham. All rights reserved.
// task - a command line task list manager.
//
// Copyright 2006 - 2008, Paul Beckingham.
// All rights reserved.
//
// This program is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free Software
// Foundation; either version 2 of the License, or (at your option) any later
// version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
// details.
//
// You should have received a copy of the GNU General Public License along with
// this program; if not, write to the
//
// Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor,
// Boston, MA
// 02110-1301
// USA
//
////////////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_T

View File

@@ -1,12 +1,34 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright 2007, 2008, Paul Beckingham. All rights reserved.
// task - a command line task list manager.
//
// Copyright 2006 - 2008, Paul Beckingham.
// All rights reserved.
//
// This program is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free Software
// Foundation; either version 2 of the License, or (at your option) any later
// version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
// details.
//
// You should have received a copy of the GNU General Public License along with
// this program; if not, write to the
//
// Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor,
// Boston, MA
// 02110-1301
// USA
//
////////////////////////////////////////////////////////////////////////////////
#include <iostream>
#include <fstream>
#include <sys/file.h>
#include <unistd.h>
#include <string.h>
#include "task.h"
#include "TDB.h"
@@ -221,7 +243,6 @@ bool TDB::addT (const T& t) const
std::vector <std::string> tags;
task.getTags (tags);
// TODO This logic smells funny.
// +tag or -tag are both considered valid tags to add to a new pending task.
// Generating an error here would not be friendly.
for (unsigned int i = 0; i < tags.size (); ++i)
@@ -306,7 +327,7 @@ bool TDB::logCommand (int argc, char** argv) const
delay (0.25);
#endif
fprintf (out, command.c_str ());
fputs (command.c_str (), out);
fclose (out);
return true;
@@ -341,7 +362,7 @@ bool TDB::overwritePending (std::vector <T>& all) const
std::vector <T>::iterator it;
for (it = all.begin (); it != all.end (); ++it)
fprintf (out, it->compose ().c_str ());
fputs (it->compose ().c_str (), out);
fclose (out);
return true;
@@ -363,7 +384,7 @@ bool TDB::writePending (const T& t) const
delay (0.25);
#endif
fprintf (out, t.compose ().c_str ());
fputs (t.compose ().c_str (), out);
fclose (out);
return true;
@@ -385,7 +406,7 @@ bool TDB::writeCompleted (const T& t) const
delay (0.25);
#endif
fprintf (out, t.compose ().c_str ());
fputs (t.compose ().c_str (), out);
fclose (out);
return true;

View File

@@ -1,6 +1,27 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright 2007, 2008, Paul Beckingham. All rights reserved.
// task - a command line task list manager.
//
// Copyright 2006 - 2008, Paul Beckingham.
// All rights reserved.
//
// This program is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free Software
// Foundation; either version 2 of the License, or (at your option) any later
// version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
// details.
//
// You should have received a copy of the GNU General Public License along with
// this program; if not, write to the
//
// Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor,
// Boston, MA
// 02110-1301
// USA
//
////////////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_TDB

View File

@@ -1,7 +1,29 @@
////////////////////////////////////////////////////////////////////////////////
// task - a command line task list manager.
//
// Copyright 2006 - 2008, Paul Beckingham.
// All rights reserved.
//
// This program is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free Software
// Foundation; either version 2 of the License, or (at your option) any later
// version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
// details.
//
// You should have received a copy of the GNU General Public License along with
// this program; if not, write to the
//
// Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor,
// Boston, MA
// 02110-1301
// USA
//
//
//
// Attributes Table Row Column Cell
// ----------------------------------------------------
@@ -22,10 +44,11 @@
//
////////////////////////////////////////////////////////////////////////////////
#include <iostream>
#include "Table.h"
#include "Date.h"
#include "stlmacros.h"
#include "task.h"
#include <string.h>
#include <assert.h>
#include <Table.h>
#include <Date.h>
#include <task.h>
////////////////////////////////////////////////////////////////////////////////
Table::Table ()
@@ -45,20 +68,20 @@ Table::~Table ()
////////////////////////////////////////////////////////////////////////////////
void Table::setTableColor (Text::color fg, Text::color bg)
{
mFg["table"] = fg;
mBg["table"] = bg;
mFg["table"] = Text::colorName (fg);
mBg["table"] = Text::colorName (bg);
}
////////////////////////////////////////////////////////////////////////////////
void Table::setTableFg (Text::color c)
{
mFg["table"] = c;
mFg["table"] = Text::colorName (c);
}
////////////////////////////////////////////////////////////////////////////////
void Table::setTableBg (Text::color c)
{
mBg["table"] = c;
mBg["table"] = Text::colorName (c);
}
////////////////////////////////////////////////////////////////////////////////
@@ -97,8 +120,8 @@ void Table::setColumnColor (int column, Text::color fg, Text::color bg)
{
char id[12];
sprintf (id, "col:%d", column);
mFg[id] = fg;
mBg[id] = bg;
mFg[id] = Text::colorName (fg);
mBg[id] = Text::colorName (bg);
}
////////////////////////////////////////////////////////////////////////////////
@@ -106,7 +129,7 @@ void Table::setColumnFg (int column, Text::color c)
{
char id[12];
sprintf (id, "col:%d", column);
mFg[id] = c;
mFg[id] = Text::colorName (c);
}
////////////////////////////////////////////////////////////////////////////////
@@ -114,7 +137,7 @@ void Table::setColumnBg (int column, Text::color c)
{
char id[12];
sprintf (id, "col:%d", column);
mBg[id] = c;
mBg[id] = Text::colorName (c);
}
////////////////////////////////////////////////////////////////////////////////
@@ -153,9 +176,7 @@ void Table::setColumnCommify (int column)
////////////////////////////////////////////////////////////////////////////////
void Table::setColumnJustification (int column, just j)
{
char id[12];
sprintf (id, "col:%d", column);
mJustification[id] = j;
mJustification[column] = j;
}
////////////////////////////////////////////////////////////////////////////////
@@ -172,36 +193,33 @@ int Table::addRow ()
}
////////////////////////////////////////////////////////////////////////////////
void Table::setRowColor (int row, Text::color fg, Text::color bg)
void Table::setRowColor (const int row, const Text::color fg, const Text::color bg)
{
char id[12];
sprintf (id, "row:%d", row);
mFg[id] = fg;
mBg[id] = bg;
mFg[id] = Text::colorName (fg);
mBg[id] = Text::colorName (bg);
}
////////////////////////////////////////////////////////////////////////////////
void Table::setRowFg (int row, Text::color c)
void Table::setRowFg (const int row, const Text::color c)
{
char id[12];
sprintf (id, "row:%d", row);
mFg[id] = c;
mFg[id] = Text::colorName (c);
}
////////////////////////////////////////////////////////////////////////////////
void Table::setRowBg (int row, Text::color c)
void Table::setRowBg (const int row, const Text::color c)
{
char id[12];
sprintf (id, "row:%d", row);
mBg[id] = c;
mBg[id] = Text::colorName (c);
}
////////////////////////////////////////////////////////////////////////////////
void Table::addCell (int row, int col, const std::string& data)
void Table::addCell (const int row, const int col, const std::string& data)
{
char id[24];
sprintf (id, "cell:%d,%d", row, col);
int length = 0;
if (mSuppressWS)
@@ -214,14 +232,14 @@ void Table::addCell (int row, int col, const std::string& data)
clean (data2);
length = data2.length ();
mData[id] = data2;
mData.add (row, col, data2);
}
else
{
if (mCommify.find (col) != mCommify.end ())
mData[id] = commify (data);
mData.add (row, col, commify (data));
else
mData[id] = data;
mData.add (row, col, data);
length = data.length ();
}
@@ -231,127 +249,114 @@ void Table::addCell (int row, int col, const std::string& data)
}
////////////////////////////////////////////////////////////////////////////////
void Table::addCell (int row, int col, char data)
void Table::addCell (const int row, const int col, const char data)
{
char id[24];
sprintf (id, "cell:%d,%d", row, col);
char value[2];
sprintf (value, "%c", data);
mData[id] = value;
mData.add (row, col, data);
// Automatically maintain max width.
mMaxDataWidth[col] = max (mMaxDataWidth[col], (signed) ::strlen (value));
mMaxDataWidth[col] = max (mMaxDataWidth[col], 1);
}
////////////////////////////////////////////////////////////////////////////////
void Table::addCell (int row, int col, int data)
void Table::addCell (const int row, const int col, const int data)
{
char id[24];
sprintf (id, "cell:%d,%d", row, col);
char value[12];
sprintf (value, "%d", data);
if (mCommify.find (col) != mCommify.end ())
mData[id] = commify (value);
mData.add (row, col, commify (value));
else
mData[id] = value;
mData.add (row, col, value);
// Automatically maintain max width.
mMaxDataWidth[col] = max (mMaxDataWidth[col], (signed) ::strlen (value));
}
////////////////////////////////////////////////////////////////////////////////
void Table::addCell (int row, int col, float data)
void Table::addCell (const int row, const int col, const float data)
{
char id[24];
sprintf (id, "cell:%d,%d", row, col);
char value[24];
sprintf (value, "%.2f", data);
if (mCommify.find (col) != mCommify.end ())
mData[id] = commify (value);
mData.add (row, col, commify (value));
else
mData[id] = value;
mData.add (row, col, value);
// Automatically maintain max width.
mMaxDataWidth[col] = max (mMaxDataWidth[col], (signed) ::strlen (value));
}
////////////////////////////////////////////////////////////////////////////////
void Table::addCell (int row, int col, double data)
void Table::addCell (const int row, const int col, const double data)
{
char id[24];
sprintf (id, "cell:%d,%d", row, col);
char value[24];
sprintf (value, "%.6f", data);
if (mCommify.find (col) != mCommify.end ())
mData[id] = commify (value);
mData.add (row, col, commify (value));
else
mData[id] = value;
mData.add (row, col, value);
// Automatically maintain max width.
mMaxDataWidth[col] = max (mMaxDataWidth[col], (signed) ::strlen (value));
}
////////////////////////////////////////////////////////////////////////////////
void Table::setCellColor (int row, int col, Text::color fg, Text::color bg)
void Table::setCellColor (const int row, const int col, const Text::color fg, const Text::color bg)
{
char id[24];
sprintf (id, "cell:%d,%d", row, col);
mFg[id] = fg;
mBg[id] = bg;
mFg[id] = Text::colorName (fg);
mBg[id] = Text::colorName (bg);
}
////////////////////////////////////////////////////////////////////////////////
void Table::setCellFg (int row, int col, Text::color c)
void Table::setCellFg (const int row, const int col, const Text::color c)
{
char id[24];
sprintf (id, "cell:%d,%d", row, col);
mFg[id] = c;
mFg[id] = Text::colorName (c);
}
////////////////////////////////////////////////////////////////////////////////
void Table::setCellBg (int row, int col, Text::color c)
void Table::setCellBg (const int row, const int col, const Text::color c)
{
char id[24];
sprintf (id, "cell:%d,%d", row, col);
mBg[id] = c;
mBg[id] = Text::colorName (c);
}
////////////////////////////////////////////////////////////////////////////////
std::string Table::getCell (int row, int col)
std::string Table::getCell (const int row, const int col)
{
char id[24];
sprintf (id, "cell:%d,%d", row, col);
return mData[id];
Grid::Cell* c = mData.byRow (row, col);
if (c)
return (std::string) *c;
return "";
}
////////////////////////////////////////////////////////////////////////////////
Text::color Table::getFg (int row, int col)
Text::color Table::getFg (const int row, const int col)
{
char idCell[24];
sprintf (idCell, "cell:%d,%d", row, col);
if (mFg.find (idCell) != mFg.end ())
return mFg[idCell];
return Text::colorCode (mFg[idCell]);
char idRow[12];
sprintf (idRow, "row:%d", row);
if (mFg.find (idRow) != mFg.end ())
return mFg[idRow];
return Text::colorCode (mFg[idRow]);
char idCol[12];
sprintf (idCol, "col:%d", col);
if (mFg.find (idCol) != mFg.end ())
return mFg[idCol];
return Text::colorCode (mFg[idCol]);
if (mFg.find ("table") != mFg.end ())
return mFg["table"];
return Text::colorCode (mFg["table"]);
return Text::nocolor;
}
@@ -362,31 +367,31 @@ Text::color Table::getHeaderFg (int col)
char idCol[12];
sprintf (idCol, "col:%d", col);
return mFg.find (idCol) != mFg.end () ? mFg[idCol]
: mFg.find ("table") != mFg.end () ? mFg["table"]
return mFg.find (idCol) != mFg.end () ? Text::colorCode (mFg[idCol])
: mFg.find ("table") != mFg.end () ? Text::colorCode (mFg["table"])
: Text::nocolor;
}
////////////////////////////////////////////////////////////////////////////////
Text::color Table::getBg (int row, int col)
Text::color Table::getBg (const int row, const int col)
{
char idCell[24];
sprintf (idCell, "cell:%d,%d", row, col);
if (mBg.find (idCell) != mBg.end ())
return mBg[idCell];
return Text::colorCode (mBg[idCell]);
char idRow[12];
sprintf (idRow, "row:%d", row);
if (mBg.find (idRow) != mBg.end ())
return mBg[idRow];
return Text::colorCode (mBg[idRow]);
char idCol[12];
sprintf (idCol, "col:%d", col);
if (mBg.find (idCol) != mBg.end ())
return mBg[idCol];
return Text::colorCode (mBg[idCol]);
if (mBg.find ("table") != mBg.end ())
return mBg["table"];
return Text::colorCode (mBg["table"]);
return Text::nocolor;
}
@@ -397,19 +402,19 @@ Text::color Table::getHeaderBg (int col)
char idCol[12];
sprintf (idCol, "col:%d", col);
return mBg.find (idCol) != mBg.end () ? mBg[idCol]
: mBg.find ("table") != mBg.end () ? mBg["table"]
return mBg.find (idCol) != mBg.end () ? Text::colorCode (mBg[idCol])
: mBg.find ("table") != mBg.end () ? Text::colorCode (mBg["table"])
: Text::nocolor;
}
////////////////////////////////////////////////////////////////////////////////
Text::attr Table::getHeaderUnderline (int col)
Text::color Table::getHeaderUnderline (int col)
{
char idCol[12];
sprintf (idCol, "col:%d", col);
return mUnderline.find (idCol) != mUnderline.end () ? Text::underline
: Text::normal;
: Text::nocolor;
}
////////////////////////////////////////////////////////////////////////////////
@@ -433,7 +438,7 @@ void Table::calculateColumnWidths ()
std::vector <int> ideal = mMaxDataWidth;
int width = 0;
int countFlexible = 0;
for (unsigned int c = 0; c < mColumns.size (); ++c)
for (size_t c = 0; c < mColumns.size (); ++c)
{
if (mSpecifiedWidth[c] == flexible)
++countFlexible;
@@ -458,7 +463,7 @@ void Table::calculateColumnWidths ()
{
ideal = mMaxDataWidth;
width = 0;
for (unsigned int c = 0; c < mColumns.size (); ++c)
for (size_t c = 0; c < mColumns.size (); ++c)
{
if (mSpecifiedWidth[c] > 0)
ideal[c] = mSpecifiedWidth[c];
@@ -480,7 +485,7 @@ void Table::calculateColumnWidths ()
int remainder = available % countFlexible;
int lastFlexible = mColumns.size () - 1;
for (unsigned int c = 0; c < mColumns.size (); ++c)
for (size_t c = 0; c < mColumns.size (); ++c)
{
if (mSpecifiedWidth[c] == flexible)
{
@@ -494,8 +499,16 @@ void Table::calculateColumnWidths ()
mCalculatedWidth = ideal;
return;
}
// else
else
{
// std::cout << "# insufficient room, considering only flexible columns." << std::endl;
// The fallback position is to assume no width was specificed, and just
// calculate widths accordingly.
mTableWidth = 0;
calculateColumnWidths ();
return;
}
}
// Try again, treating minimum columns as flexible.
@@ -503,22 +516,10 @@ void Table::calculateColumnWidths ()
}
////////////////////////////////////////////////////////////////////////////////
Table::just Table::getJustification (int row, int col)
Table::just Table::getJustification (const int row, const int col)
{
char idCell[24];
sprintf (idCell, "cell:%d,%d", row, col);
if (mJustification.find (idCell) != mJustification.end ())
return mJustification[idCell];
char idRow[12];
sprintf (idRow, "row:%d", row);
if (mJustification.find (idRow) != mJustification.end ())
return mJustification[idRow];
char idCol[12];
sprintf (idCol, "col:%d", col);
if (mJustification.find (idCol) != mJustification.end ())
return mJustification[idCol];
if (mJustification.find (col) != mJustification.end ())
return mJustification[col];
return left;
}
@@ -526,11 +527,7 @@ Table::just Table::getJustification (int row, int col)
////////////////////////////////////////////////////////////////////////////////
Table::just Table::getHeaderJustification (int col)
{
char idCol[12];
sprintf (idCol, "col:%d", col);
return mJustification.find (idCol) != mJustification.end () ? mJustification[idCol]
: mJustification.find ("table") != mJustification.end () ? mJustification["table"]
return mJustification.find (col) != mJustification.end () ? mJustification[col]
: left;
}
@@ -556,42 +553,17 @@ const std::string Table::formatHeader (
{
assert (width > 0);
Text::color fg = getHeaderFg (col);
Text::color bg = getHeaderBg (col);
std::string data = mColumns[col];
Text::attr decoration = getHeaderUnderline (col);
Text::color fg = getHeaderFg (col);
Text::color bg = getHeaderBg (col);
std::string data = mColumns[col];
Text::color decoration = getHeaderUnderline (col);
std::string colorOn = "";
std::string pad = "";
std::string intraPad = "";
std::string preJust = "";
std::string attrOn = "";
std::string attrOff = "";
std::string postJust = "";
std::string colorOff = "";
if (fg != Text::nocolor)
{
char c[12];
sprintf (c, "\033[%dm", fg + 29);
colorOn += c;
}
if (bg != Text::nocolor)
{
char c[12];
sprintf (c, "\033[%dm", bg + 39);
colorOn += c;
}
if (colorOn != "")
colorOff += "\033[0m";
if (decoration == Text::underline)
{
attrOn = "\033[4m";
attrOff = "\033[0m";
}
for (int i = 0; i < padding; ++i)
pad += " ";
@@ -606,24 +578,19 @@ const std::string Table::formatHeader (
for (int i = 0; i < getIntraPadding (); ++i)
intraPad += " ";
return colorOn +
attrOn +
pad +
preJust +
data +
postJust +
pad +
attrOff +
intraPad +
colorOff;
return Text::colorize (
fg, bg,
Text::colorize (
decoration, Text::nocolor,
pad + preJust+ data + postJust + pad) + intraPad);
}
////////////////////////////////////////////////////////////////////////////////
void Table::formatCell (
int row,
int col,
int width,
int padding,
const int row,
const int col,
const int width,
const int padding,
std::vector <std::string>& lines,
std::string& blank)
{
@@ -634,27 +601,8 @@ void Table::formatCell (
just justification = getJustification (row, col);
std::string data = getCell (row, col);
std::string colorOn = "";
std::string pad = "";
std::string intraPad = "";
std::string colorOff = "";
if (fg != Text::nocolor)
{
char c[12];
sprintf (c, "\033[%dm", fg + 29);
colorOn += c;
}
if (bg != Text::nocolor)
{
char c[12];
sprintf (c, "\033[%dm", bg + 39);
colorOn += c;
}
if (fg != Text::nocolor || bg != Text::nocolor)
colorOff += "\033[0m";
for (int i = 0; i < padding; ++i)
pad += " ";
@@ -668,7 +616,7 @@ void Table::formatCell (
std::string postJust;
std::vector <std::string> chunks;
wrapText (chunks, data, width);
for (unsigned int chunk = 0; chunk < chunks.size (); ++chunk)
for (size_t chunk = 0; chunk < chunks.size (); ++chunk)
{
// Place the data within the available space - justify.
int gap = width - chunks[chunk].length ();
@@ -689,19 +637,12 @@ void Table::formatCell (
for (int i = 0; i < gap / 2; ++i)
preJust += " ";
for (unsigned int i = 0; i < gap - preJust.length (); ++i)
for (size_t i = 0; i < gap - preJust.length (); ++i)
postJust += " ";
}
lines.push_back (
colorOn +
pad +
preJust +
chunks[chunk] +
postJust +
pad +
intraPad +
colorOff);
Text::colorize (fg, bg, pad + preJust + chunks[chunk] + postJust + pad + intraPad));
}
// The blank is used to vertically pad cells that have blank lines.
@@ -709,88 +650,7 @@ void Table::formatCell (
for (int i = 0; i < width; ++i)
pad += " ";
blank =
colorOn +
pad +
intraPad +
colorOff;
}
////////////////////////////////////////////////////////////////////////////////
const std::string Table::formatCell (
int row,
int col,
int width,
int padding)
{
assert (width > 0);
Text::color fg = getFg (row, col);
Text::color bg = getBg (row, col);
just justification = getJustification (row, col);
std::string data = getCell (row, col);
std::string colorOn = "";
std::string pad = "";
std::string intraPad = "";
std::string preJust = "";
std::string postJust = "";
std::string colorOff = "";
if (fg != Text::nocolor)
{
char c[12];
sprintf (c, "\033[%dm", fg + 29);
colorOn += c;
}
if (bg != Text::nocolor)
{
char c[12];
sprintf (c, "\033[%dm", bg + 39);
colorOn += c;
}
if (fg != Text::nocolor || bg != Text::nocolor)
colorOff += "\033[0m";
for (int i = 0; i < padding; ++i)
pad += " ";
// Place the data within the available space - justify.
int gap = width - data.length ();
if (justification == left)
{
for (int i = 0; i < gap; ++i)
postJust += " ";
}
else if (justification == right)
{
for (int i = 0; i < gap; ++i)
preJust += " ";
}
else if (justification == center)
{
for (int i = 0; i < gap / 2; ++i)
preJust += " ";
for (unsigned int i = 0; i < gap - preJust.length (); ++i)
postJust += " ";
}
if (col < (signed) mColumns.size () - 1)
for (int i = 0; i < getIntraPadding (); ++i)
intraPad += " ";
return colorOn +
pad +
preJust +
data +
postJust +
pad +
intraPad +
colorOff;
blank = Text::colorize (fg, bg, pad + intraPad);
}
////////////////////////////////////////////////////////////////////////////////
@@ -799,6 +659,12 @@ void Table::suppressWS ()
mSuppressWS = true;
}
////////////////////////////////////////////////////////////////////////////////
void Table::setDateFormat (const std::string& dateFormat)
{
mDateFormat = dateFormat;
}
////////////////////////////////////////////////////////////////////////////////
int Table::rowCount ()
{
@@ -818,15 +684,15 @@ int Table::columnCount ()
// - removal of redundant color codes:
// ^[[31mName^[[0m ^[[31mValue^[[0m -> ^[[31mName Value^[[0m
//
// This method is a work in progress.
void Table::optimize (std::string& output)
{
/*
TODO Unoptimized length.
int start = output.length ();
*/
// \s\n -> \n
unsigned int i = 0;
size_t i = 0;
while ((i = output.find (" \n")) != std::string::npos)
{
output = output.substr (0, i) +
@@ -834,7 +700,6 @@ void Table::optimize (std::string& output)
}
/*
TODO This code displays the % reduction of the optimize function.
std::cout << int ((100 * (start - output.length ()) / start))
<< "%" << std::endl;
*/
@@ -869,52 +734,51 @@ void Table::sort (std::vector <int>& order)
while (r + gap < (int) order.size ())
{
bool keepScanning = true;
for (unsigned int c = 0; keepScanning && c < mSortColumns.size (); ++c)
for (size_t c = 0; keepScanning && c < mSortColumns.size (); ++c)
{
keepScanning = false;
char left[16];
sprintf (left, "cell:%d,%d", order[r], mSortColumns[c]);
Grid::Cell* left = mData.byRow (order[r], mSortColumns[c]);
Grid::Cell* right = mData.byRow (order[r + gap], mSortColumns[c]);
if (left == NULL && right != NULL)
SWAP
char right[16];
sprintf (right, "cell:%d,%d", order[r + gap], mSortColumns[c]);
if (mData[left] != mData[right])
if (left && right && *left != *right)
{
switch (mSortOrder[mSortColumns[c]])
{
case ascendingNumeric:
if (::atoi (mData[left].c_str ()) > ::atoi (mData[right].c_str ()))
if ((float)*left > (float)*right)
SWAP
break;
case descendingNumeric:
if (::atoi (mData[left].c_str ()) < ::atoi (mData[right].c_str ()))
if ((float)*left < (float)*right)
SWAP
break;
case ascendingCharacter:
if (mData[left] > mData[right])
if ((char)*left > (char)*right)
SWAP
break;
case descendingCharacter:
if (mData[left] < mData[right])
if ((char)*left < (char)*right)
SWAP
break;
case ascendingDate:
{
if (mData[left] != "" && mData[right] == "")
if ((std::string)*left != "" && (std::string)*right == "")
break;
else if (mData[left] == "" && mData[right] != "")
else if ((std::string)*left == "" && (std::string)*right != "")
SWAP
else
{
Date dl (mData[left]);
Date dr (mData[right]);
Date dl ((std::string)*left, mDateFormat);
Date dr ((std::string)*right, mDateFormat);
if (dl > dr)
SWAP
}
@@ -923,16 +787,16 @@ void Table::sort (std::vector <int>& order)
case descendingDate:
{
if (mData[left] != "" && mData[right] == "")
if ((std::string)*left != "" && (std::string)*right == "")
break;
else if (mData[left] == "" && mData[right] != "")
else if ((std::string)*left == "" && (std::string)*right != "")
SWAP
else
{
Date dl (mData[left]);
Date dr (mData[right]);
Date dl ((std::string)*left, mDateFormat);
Date dr ((std::string)*right, mDateFormat);
if (dl < dr)
SWAP
}
@@ -940,16 +804,16 @@ void Table::sort (std::vector <int>& order)
break;
case ascendingPriority:
if ((mData[left] == "" && mData[right] != "") ||
(mData[left] == "M" && mData[right] == "L") ||
(mData[left] == "H" && (mData[right] == "L" || mData[right] == "M")))
if (((std::string)*left == "" && (std::string)*right != "") ||
((std::string)*left == "M" && (std::string)*right == "L") ||
((std::string)*left == "H" && ((std::string)*right == "L" || (std::string)*right == "M")))
SWAP
break;
case descendingPriority:
if ((mData[left] == "" && mData[right] != "") ||
(mData[left] == "L" && (mData[right] == "M" || mData[right] == "H")) ||
(mData[left] == "M" && mData[right] == "H"))
if (((std::string)*left == "" && (std::string)*right != "") ||
((std::string)*left == "L" && ((std::string)*right == "M" || (std::string)*right == "H")) ||
((std::string)*left == "M" && (std::string)*right == "H"))
SWAP
break;
}
@@ -968,8 +832,8 @@ void Table::sort (std::vector <int>& order)
////////////////////////////////////////////////////////////////////////////////
void Table::clean (std::string& value)
{
unsigned int start = 0;
unsigned int pos;
size_t start = 0;
size_t pos;
while ((pos = value.find ('\t', start)) != std::string::npos)
{
value.replace (pos, 1, " ");
@@ -997,7 +861,7 @@ const std::string Table::render ()
// Print column headers in column order.
std::string output;
for (unsigned int col = 0; col < mColumns.size (); ++col)
for (size_t col = 0; col < mColumns.size (); ++col)
output += formatHeader (
col,
mCalculatedWidth[col],
@@ -1020,8 +884,8 @@ const std::string Table::render ()
std::vector <std::vector <std::string> > columns;
std::vector <std::string> blanks;
unsigned int maxHeight = 0;
for (unsigned int col = 0; col < mColumns.size (); ++col)
size_t maxHeight = 0;
for (size_t col = 0; col < mColumns.size (); ++col)
{
std::vector <std::string> lines;
std::string blank;
@@ -1041,9 +905,9 @@ const std::string Table::render ()
if (maxHeight)
{
for (unsigned int lines = 0; lines < maxHeight; ++lines)
for (size_t lines = 0; lines < maxHeight; ++lines)
{
for (unsigned int col = 0; col < mColumns.size (); ++col)
for (size_t col = 0; col < mColumns.size (); ++col)
if (lines < columns[col].size ())
output += columns[col][lines];
else

View File

@@ -1,8 +1,28 @@
////////////////////////////////////////////////////////////////////////////////
// task - a command line task list manager.
//
// Copyright 2006 - 2008, Paul Beckingham.
// All rights reserved.
//
// TODO Implement height
// This program is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free Software
// Foundation; either version 2 of the License, or (at your option) any later
// version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
// details.
//
// You should have received a copy of the GNU General Public License along with
// this program; if not, write to the
//
// Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor,
// Boston, MA
// 02110-1301
// USA
//
////////////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_TABLE
#define INCLUDED_TABLE
@@ -10,7 +30,8 @@
#include <map>
#include <vector>
#include <string>
#include "color.h"
#include <color.h>
#include <Grid.h>
class Table
{
@@ -58,26 +79,26 @@ public:
void setCellBg (int, int, Text::color);
void suppressWS ();
void setDateFormat (const std::string&);
int rowCount ();
int columnCount ();
const std::string render ();
private:
std::string getCell (int, int);
Text::color getFg (int, int);
Text::color getHeaderFg (int);
Text::color getBg (int, int);
Text::color getHeaderBg (int);
Text::attr getHeaderUnderline (int);
int getPadding (int);
std::string getCell (const int, const int);
Text::color getFg (const int, const int);
Text::color getHeaderFg (const int);
Text::color getBg (const int, const int);
Text::color getHeaderBg (const int);
Text::color getHeaderUnderline (const int);
int getPadding (const int);
int getIntraPadding ();
void calculateColumnWidths ();
just getJustification (int, int);
just getHeaderJustification (int);
const std::string formatHeader (int, int, int);
const std::string formatCell (int, int, int, int);
void formatCell (int, int, int, int, std::vector <std::string>&, std::string&);
just getJustification (const int, const int);
just getHeaderJustification (const int);
const std::string formatHeader (const int, const int, const int);
void formatCell (const int, const int, const int, const int, std::vector <std::string>&, std::string&);
void optimize (std::string&);
void sort (std::vector <int>&);
void clean (std::string&);
@@ -86,9 +107,9 @@ private:
std::vector <std::string> mColumns;
int mRows;
int mIntraPadding;
std::map <std::string, Text::color> mFg;
std::map <std::string, Text::color> mBg;
std::map <std::string, Text::attr> mUnderline;
std::map <std::string, std::string> mFg;
std::map <std::string, std::string> mBg;
std::map <std::string, std::string> mUnderline;
// Padding...
int mTablePadding;
@@ -100,14 +121,15 @@ private:
std::vector <int> mMaxDataWidth;
std::vector <int> mCalculatedWidth;
std::map <std::string, just> mJustification;
std::map <int, just> mJustification;
std::map <int, bool> mCommify;
std::map <std::string, std::string> mData;
Grid mData;
std::vector <int> mSortColumns;
std::map <int, order> mSortOrder;
// Misc...
bool mSuppressWS;
std::string mDateFormat;
};
#endif

View File

@@ -1,64 +1,261 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright 2008, Paul Beckingham. All rights reserved.
// task - a command line task list manager.
//
// Copyright 2006 - 2008, Paul Beckingham.
// All rights reserved.
//
// This program is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free Software
// Foundation; either version 2 of the License, or (at your option) any later
// version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
// details.
//
// You should have received a copy of the GNU General Public License along with
// this program; if not, write to the
//
// Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor,
// Boston, MA
// 02110-1301
// USA
//
////////////////////////////////////////////////////////////////////////////////
#include <string>
#include "color.h"
////////////////////////////////////////////////////////////////////////////////
std::string Text::colorName (Text::color c)
namespace Text
{
std::string colorName (color c)
{
switch (c)
{
case black: return "black";
case red: return "red";
case green: return "green";
case yellow: return "yellow";
case blue: return "blue";
case magenta: return "magenta";
case cyan: return "cyan";
case white: return "white";
case nocolor: return "";
case nocolor: return "";
case off: return "off";
case bold: return "bold";
case underline: return "underline";
case bold_underline: return "bold_underline";
case black: return "black";
case red: return "red";
case green: return "green";
case yellow: return "yellow";
case blue: return "blue";
case magenta: return "magenta";
case cyan: return "cyan";
case white: return "white";
case bold_black: return "bold_black";
case bold_red: return "bold_red";
case bold_green: return "bold_green";
case bold_yellow: return "bold_yellow";
case bold_blue: return "bold_blue";
case bold_magenta: return "bold_magenta";
case bold_cyan: return "bold_cyan";
case bold_white: return "bold_white";
case underline_black: return "underline_black";
case underline_red: return "underline_red";
case underline_green: return "underline_green";
case underline_yellow: return "underline_yellow";
case underline_blue: return "underline_blue";
case underline_magenta: return "underline_magenta";
case underline_cyan: return "underline_cyan";
case underline_white: return "underline_white";
case bold_underline_black: return "bold_underline_black";
case bold_underline_red: return "bold_underline_red";
case bold_underline_green: return "bold_underline_green";
case bold_underline_yellow: return "bold_underline_yellow";
case bold_underline_blue: return "bold_underline_blue";
case bold_underline_magenta: return "bold_underline_magenta";
case bold_underline_cyan: return "bold_underline_cyan";
case bold_underline_white: return "bold_underline_white";
case on_black: return "on_black";
case on_red: return "on_red";
case on_green: return "on_green";
case on_yellow: return "on_yellow";
case on_blue: return "on_blue";
case on_magenta: return "on_magenta";
case on_cyan: return "on_cyan";
case on_white: return "on_white";
case on_bright_black: return "on_bright_black";
case on_bright_red: return "on_bright_red";
case on_bright_green: return "on_bright_green";
case on_bright_yellow: return "on_bright_yellow";
case on_bright_blue: return "on_bright_blue";
case on_bright_magenta: return "on_bright_magenta";
case on_bright_cyan: return "on_bright_cyan";
case on_bright_white: return "on_bright_white";
default: throw "Unknown Text::color value";
}
return "";
}
////////////////////////////////////////////////////////////////////////////////
Text::color Text::colorCode (const std::string& c)
color colorCode (const std::string& c)
{
if (c == "black") return black;
if (c == "red") return red;
if (c == "green") return green;
if (c == "yellow") return yellow;
if (c == "blue") return blue;
if (c == "magenta") return magenta;
if (c == "cyan") return cyan;
if (c == "white") return white;
if (c == "off") return off;
else if (c == "bold") return bold;
else if (c == "underline") return underline;
else if (c == "bold_underline") return bold_underline;
else if (c == "black") return black;
else if (c == "red") return red;
else if (c == "green") return green;
else if (c == "yellow") return yellow;
else if (c == "blue") return blue;
else if (c == "magenta") return magenta;
else if (c == "cyan") return cyan;
else if (c == "white") return white;
else if (c == "bold_black") return bold_black;
else if (c == "bold_red") return bold_red;
else if (c == "bold_green") return bold_green;
else if (c == "bold_yellow") return bold_yellow;
else if (c == "bold_blue") return bold_blue;
else if (c == "bold_magenta") return bold_magenta;
else if (c == "bold_cyan") return bold_cyan;
else if (c == "bold_white") return bold_white;
else if (c == "underline_black") return underline_black;
else if (c == "underline_red") return underline_red;
else if (c == "underline_green") return underline_green;
else if (c == "underline_yellow") return underline_yellow;
else if (c == "underline_blue") return underline_blue;
else if (c == "underline_magenta") return underline_magenta;
else if (c == "underline_cyan") return underline_cyan;
else if (c == "underline_white") return underline_white;
else if (c == "bold_underline_black") return bold_underline_black;
else if (c == "bold_underline_red") return bold_underline_red;
else if (c == "bold_underline_green") return bold_underline_green;
else if (c == "bold_underline_yellow") return bold_underline_yellow;
else if (c == "bold_underline_blue") return bold_underline_blue;
else if (c == "bold_underline_magenta") return bold_underline_magenta;
else if (c == "bold_underline_cyan") return bold_underline_cyan;
else if (c == "bold_underline_white") return bold_underline_white;
else if (c == "on_black") return on_black;
else if (c == "on_red") return on_red;
else if (c == "on_green") return on_green;
else if (c == "on_yellow") return on_yellow;
else if (c == "on_blue") return on_blue;
else if (c == "on_magenta") return on_magenta;
else if (c == "on_cyan") return on_cyan;
else if (c == "on_white") return on_white;
else if (c == "on_bright_black") return on_bright_black;
else if (c == "on_bright_red") return on_bright_red;
else if (c == "on_bright_green") return on_bright_green;
else if (c == "on_bright_yellow") return on_bright_yellow;
else if (c == "on_bright_blue") return on_bright_blue;
else if (c == "on_bright_magenta") return on_bright_magenta;
else if (c == "on_bright_cyan") return on_bright_cyan;
else if (c == "on_bright_white") return on_bright_white;
return nocolor;
}
////////////////////////////////////////////////////////////////////////////////
std::string Text::attrName (Text::attr a)
std::string decode (color c)
{
switch (a)
switch (c)
{
case underline: return "underline";
case normal: return "";
case nocolor: return "";
case off: return "\033[0m";
case bold: return "\033[1m";
case underline: return "\033[4m";
case bold_underline: return "\033[1;4m";
case black: return "\033[30m";
case red: return "\033[31m";
case green: return "\033[32m";
case yellow: return "\033[33m";
case blue: return "\033[34m";
case magenta: return "\033[35m";
case cyan: return "\033[36m";
case white: return "\033[37m";
case bold_black: return "\033[90m";
case bold_red: return "\033[91m";
case bold_green: return "\033[92m";
case bold_yellow: return "\033[93m";
case bold_blue: return "\033[94m";
case bold_magenta: return "\033[95m";
case bold_cyan: return "\033[96m";
case bold_white: return "\033[97m";
case underline_black: return "\033[4;30m";
case underline_red: return "\033[4;31m";
case underline_green: return "\033[4;32m";
case underline_yellow: return "\033[4;33m";
case underline_blue: return "\033[4;34m";
case underline_magenta: return "\033[4;35m";
case underline_cyan: return "\033[4;36m";
case underline_white: return "\033[4;37m";
case bold_underline_black: return "\033[1;4;30m";
case bold_underline_red: return "\033[1;4;31m";
case bold_underline_green: return "\033[1;4;32m";
case bold_underline_yellow: return "\033[1;4;33m";
case bold_underline_blue: return "\033[1;4;34m";
case bold_underline_magenta: return "\033[1;4;35m";
case bold_underline_cyan: return "\033[1;4;36m";
case bold_underline_white: return "\033[1;4;37m";
case on_black: return "\033[40m";
case on_red: return "\033[41m";
case on_green: return "\033[42m";
case on_yellow: return "\033[43m";
case on_blue: return "\033[44m";
case on_magenta: return "\033[45m";
case on_cyan: return "\033[46m";
case on_white: return "\033[47m";
case on_bright_black: return "\033[100m";
case on_bright_red: return "\033[101m";
case on_bright_green: return "\033[102m";
case on_bright_yellow: return "\033[103m";
case on_bright_blue: return "\033[104m";
case on_bright_magenta: return "\033[105m";
case on_bright_cyan: return "\033[106m";
case on_bright_white: return "\033[107m";
default: throw "Unknown Text::color value";
}
return "";
}
////////////////////////////////////////////////////////////////////////////////
Text::attr Text::attrCode (const std::string& a)
std::string colorize (color fg, color bg, const std::string& input)
{
if (a == "underline") return underline;
return normal;
return decode (fg) + decode (bg) + input + decode (off);
}
////////////////////////////////////////////////////////////////////////////////
std::string colorize (color fg, color bg)
{
return decode (fg) + decode (bg);
}
////////////////////////////////////////////////////////////////////////////////
std::string colorize ()
{
return decode (off);
}
////////////////////////////////////////////////////////////////////////////////
}

View File

@@ -1,21 +1,55 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright 2008, Paul Beckingham.
// task - a command line task list manager.
//
// Copyright 2006 - 2008, Paul Beckingham.
// All rights reserved.
//
// This program is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free Software
// Foundation; either version 2 of the License, or (at your option) any later
// version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
// details.
//
// You should have received a copy of the GNU General Public License along with
// this program; if not, write to the
//
// Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor,
// Boston, MA
// 02110-1301
// USA
//
////////////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_COLOR
#define INCLUDED_COLOR
namespace Text
{
enum color {nocolor = 0, black, red, green, yellow, blue, magenta, cyan, white};
enum attr {normal = 0, underline};
enum color
{
nocolor = 0,
off,
bold, underline, bold_underline,
black, bold_black, underline_black, bold_underline_black, on_black, on_bright_black,
red, bold_red, underline_red, bold_underline_red, on_red, on_bright_red,
green, bold_green, underline_green, bold_underline_green, on_green, on_bright_green,
yellow, bold_yellow, underline_yellow, bold_underline_yellow, on_yellow, on_bright_yellow,
blue, bold_blue, underline_blue, bold_underline_blue, on_blue, on_bright_blue,
magenta, bold_magenta, underline_magenta, bold_underline_magenta, on_magenta, on_bright_magenta,
cyan, bold_cyan, underline_cyan, bold_underline_cyan, on_cyan, on_bright_cyan,
white, bold_white, underline_white, bold_underline_white, on_white, on_bright_white
};
std::string colorName (Text::color);
Text::color colorCode (const std::string&);
std::string colorName (color);
color colorCode (const std::string&);
std::string attrName (Text::attr);
Text::attr attrCode (const std::string&);
std::string colorize (color, color, const std::string& string);
std::string colorize (color, color);
std::string colorize ();
}
#endif

View File

@@ -1,49 +0,0 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright 2004 - 2008, Paul Beckingham. All rights reserved.
//
//
////////////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_LIBRARY
#define INCLUDED_LIBRARY
#include <string>
#include <vector>
#include <sys/types.h>
#include "stlmacros.h"
#ifndef max
#define max(a,b) ((a) > (b) ? (a) : (b))
#endif
// text.cpp
void wrapText (std::vector <std::string>&, const std::string&, const int);
std::string trimLeft (const std::string& in, const std::string& t = " ");
std::string trimRight (const std::string& in, const std::string& t = " ");
std::string trim (const std::string& in, const std::string& t = " ");
std::wstring trimLeft (const std::wstring& in, const std::wstring& t = L" "); // UNICODE safe
std::wstring trimRight (const std::wstring& in, const std::wstring& t = L" "); // UNICODE safe
std::wstring trim (const std::wstring& in, const std::wstring& t = L" "); // UNICODE safe
void extractParagraphs (const std::string&, std::vector<std::string>&);
void extractLine (std::string&, std::string&, int);
void split (std::vector<std::string>&, const std::string&, const char);
void split (std::vector<std::string>&, const std::string&, const std::string&);
void join (std::string&, const std::string&, const std::vector<std::string>&);
std::string commify (const std::string&);
std::string lowerCase (const std::string&);
// misc.cpp
void delay (float);
// list.cpp
int autoComplete (const std::string&, const std::vector<std::string>&, std::vector<std::string>&);
// units.cpp
void formatTimeDeltaDays (std::string&, time_t);
std::string formatSeconds (time_t);
// uuid.cpp
const std::string uuid ();
#endif
////////////////////////////////////////////////////////////////////////////////

View File

@@ -1,9 +1,31 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright 2006 - 2008, Paul Beckingham. All rights reserved.
// task - a command line task list manager.
//
// Copyright 2006 - 2008, Paul Beckingham.
// All rights reserved.
//
// This program is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free Software
// Foundation; either version 2 of the License, or (at your option) any later
// version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
// details.
//
// You should have received a copy of the GNU General Public License along with
// this program; if not, write to the
//
// Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor,
// Boston, MA
// 02110-1301
// USA
//
////////////////////////////////////////////////////////////////////////////////
#include <iostream>
#include <stdlib.h>
#include <string>
#include <vector>
#include <map>
@@ -13,20 +35,69 @@
#include "T.h"
////////////////////////////////////////////////////////////////////////////////
static char* colors[] =
static const char* colors[] =
{
"bold",
"underline",
"bold_underline",
"black",
"blue",
"red",
"green",
"yellow",
"blue",
"magenta",
"cyan",
"yellow",
"white",
"bold_black",
"bold_red",
"bold_green",
"bold_yellow",
"bold_blue",
"bold_magenta",
"bold_cyan",
"bold_white",
"underline_black",
"underline_red",
"underline_green",
"underline_yellow",
"underline_blue",
"underline_magenta",
"underline_cyan",
"underline_white",
"bold_underline_black",
"bold_underline_red",
"bold_underline_green",
"bold_underline_yellow",
"bold_underline_blue",
"bold_underline_magenta",
"bold_underline_cyan",
"bold_underline_white",
"on_black",
"on_red",
"on_green",
"on_yellow",
"on_blue",
"on_magenta",
"on_cyan",
"on_white",
"on_bright_black",
"on_bright_red",
"on_bright_green",
"on_bright_yellow",
"on_bright_blue",
"on_bright_magenta",
"on_bright_cyan",
"on_bright_white",
"",
};
static char* attributes[] =
static const char* attributes[] =
{
"project",
"priority",
@@ -39,11 +110,12 @@ static char* attributes[] =
"",
};
static char* commands[] =
static const char* commands[] =
{
"active",
"add",
"calendar",
"colors",
"completed",
"delete",
"done",
@@ -65,7 +137,7 @@ static char* commands[] =
"",
};
void guess (const std::string& type, char** list, std::string& candidate)
void guess (const std::string& type, const char** list, std::string& candidate)
{
std::vector <std::string> options;
for (int i = 0; list[i][0]; ++i)
@@ -86,7 +158,7 @@ void guess (const std::string& type, char** list, std::string& candidate)
error += " '";
error += candidate;
error += "' - could be either of ";
for (unsigned int i = 0; i < matches.size (); ++i)
for (size_t i = 0; i < matches.size (); ++i)
{
if (i)
error += ", ";
@@ -113,29 +185,13 @@ static bool isCommand (const std::string& candidate)
}
////////////////////////////////////////////////////////////////////////////////
bool validDate (std::string& date)
bool validDate (std::string& date, Config& conf)
{
unsigned int firstSlash = date.find ("/");
unsigned int secondSlash = date.find ("/", firstSlash + 1);
if (firstSlash != std::string::npos &&
secondSlash != std::string::npos)
{
int m = ::atoi (date.substr (0, firstSlash ).c_str ());
int d = ::atoi (date.substr (firstSlash + 1, secondSlash - firstSlash).c_str ());
int y = ::atoi (date.substr (secondSlash + 1, std::string::npos ).c_str ());
if (!Date::valid (m, d, y))
throw std::string ("\"") + date + "\" is not a valid date.";
Date test (date, conf.get ("dateformat", "m/d/Y"));
// Convert to epoch form.
Date dt (m, d, y);
time_t t;
dt.toEpoch (t);
char converted[12];
sprintf (converted, "%u", (unsigned int) t);
date = converted;
}
else
throw std::string ("Badly formed date - use the MM/DD/YYYY format");
char epoch[12];
sprintf (epoch, "%d", (int) test.toEpoch ());
date = epoch;
return true;
}
@@ -155,7 +211,7 @@ static bool validPriority (std::string& input)
}
////////////////////////////////////////////////////////////////////////////////
static bool validAttribute (std::string& name, std::string& value)
static bool validAttribute (std::string& name, std::string& value, Config& conf)
{
guess ("attribute", attributes, name);
@@ -163,7 +219,7 @@ static bool validAttribute (std::string& name, std::string& value)
guess ("color", colors, value);
else if (name == "due" && value != "")
validDate (value);
validDate (value, conf);
else if (name == "priority")
{
@@ -186,7 +242,7 @@ static bool validAttribute (std::string& name, std::string& value)
////////////////////////////////////////////////////////////////////////////////
static bool validId (const std::string& input)
{
for (unsigned int i = 0; i < input.length (); ++i)
for (size_t i = 0; i < input.length (); ++i)
if (!::isdigit (input[i]))
return false;
@@ -225,13 +281,13 @@ static bool validSubstitution (
std::string& from,
std::string& to)
{
unsigned int first = input.find ('/');
size_t first = input.find ('/');
if (first != std::string::npos)
{
unsigned int second = input.find ('/', first + 1);
size_t second = input.find ('/', first + 1);
if (second != std::string::npos)
{
unsigned int third = input.find ('/', second + 1);
size_t third = input.find ('/', second + 1);
if (third != std::string::npos)
{
if (first == 0 &&
@@ -263,15 +319,16 @@ static bool validSubstitution (
void parse (
std::vector <std::string>& args,
std::string& command,
T& task)
T& task,
Config& conf)
{
command = "";
std::string descCandidate = "";
for (unsigned int i = 0; i < args.size (); ++i)
for (size_t i = 0; i < args.size (); ++i)
{
std::string arg (args[i]);
unsigned int colon; // Pointer to colon in argument.
size_t colon; // Pointer to colon in argument.
std::string from;
std::string to;
@@ -297,7 +354,7 @@ void parse (
std::string name = arg.substr (0, colon);
std::string value = arg.substr (colon + 1, std::string::npos);
if (validAttribute (name, value))
if (validAttribute (name, value, conf))
task.setAttribute (name, value);
}

View File

@@ -1,9 +1,31 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright 2006 - 2008, Paul Beckingham. All rights reserved.
// task - a command line task list manager.
//
// Copyright 2006 - 2008, Paul Beckingham.
// All rights reserved.
//
// This program is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free Software
// Foundation; either version 2 of the License, or (at your option) any later
// version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
// details.
//
// You should have received a copy of the GNU General Public License along with
// this program; if not, write to the
//
// Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor,
// Boston, MA
// 02110-1301
// USA
//
////////////////////////////////////////////////////////////////////////////////
#include <iostream>
#include <stdlib.h>
#include "Config.h"
#include "Table.h"
#include "Date.h"
@@ -16,8 +38,8 @@ static std::map <std::string, Text::color> gsBg;
////////////////////////////////////////////////////////////////////////////////
// There are three supported variants:
// 1) "fg"
// 2) "on bg"
// 3) "fg on bg"
// 2) "bg"
// 3) "fg bg"
static void parseColorRule (
const std::string& rule,
Text::color& fg,
@@ -25,41 +47,18 @@ static void parseColorRule (
{
fg = Text::nocolor;
bg = Text::nocolor;
bool error = false;
std::vector <std::string> words;
split (words, rule, ' ');
switch (words.size ())
std::vector <std::string>::iterator it;
for (it = words.begin (); it != words.end (); ++it)
{
case 1: // "fg" - no spaces.
fg = Text::colorCode (words[0]);
break;
case 2: // "on bg" - one space, "on" before.
if (words[0] == "on")
bg = Text::colorCode (words[1]);
if (it->substr (0, 3) == "on_")
bg = Text::colorCode (*it);
else
error = true;
break;
case 3: // "fg on bg" - two spaces, "on" between them.
if (words[1] == "on")
{
fg = Text::colorCode (words[0]);
bg = Text::colorCode (words[2]);
}
else
error = true;
break;
case 0:
default:
error = true;
break;
fg = Text::colorCode (*it);
}
if (error)
std::cout << "Malformed color rule '" << rule << "'" << std::endl;
}
////////////////////////////////////////////////////////////////////////////////
@@ -83,8 +82,8 @@ void initializeColorRules (Config& conf)
////////////////////////////////////////////////////////////////////////////////
void autoColorize (T& task, Text::color& fg, Text::color& bg)
{
fg = Text::nocolor;
bg = Text::nocolor;
// Note: fg, bg already contain colors specifically assigned via command.
// TODO These rules form a hierarchy - the last rule is king.
// Colorization of the tagged.
if (gsFg["color.tagged"] != Text::nocolor ||
@@ -176,6 +175,50 @@ void autoColorize (T& task, Text::color& fg, Text::color& bg)
bg = gsBg["color.due"];
}
}
// Colorization by tag value.
std::map <std::string, Text::color>::iterator it;
for (it = gsFg.begin (); it != gsFg.end (); ++it)
{
if (it->first.substr (0, 10) == "color.tag.")
{
std::string value = it->first.substr (10, std::string::npos);
if (task.hasTag (value))
{
fg = gsFg[it->first];
bg = gsBg[it->first];
}
}
}
// Colorization by project name.
for (it = gsFg.begin (); it != gsFg.end (); ++it)
{
if (it->first.substr (0, 14) == "color.project.")
{
std::string value = it->first.substr (14, std::string::npos);
if (task.getAttribute ("project") == value)
{
fg = gsFg[it->first];
bg = gsBg[it->first];
}
}
}
// Colorization by keyword.
for (it = gsFg.begin (); it != gsFg.end (); ++it)
{
if (it->first.substr (0, 14) == "color.keyword.")
{
std::string value = lowerCase (it->first.substr (14, std::string::npos));
std::string desc = lowerCase (task.getDescription ());
if (desc.find (value) != std::string::npos)
{
fg = gsFg[it->first];
bg = gsBg[it->first];
}
}
}
}
////////////////////////////////////////////////////////////////////////////////

View File

@@ -1,18 +0,0 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright 2006 - 2008, Paul Beckingham. All rights reserved.
//
//
////////////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_STLMACROS
#define INCLUDED_STLMACROS
#define foreach(i, c) \
for (typeof (c) *foreach_p = & (c); \
foreach_p; \
foreach_p = 0) \
for (typeof (foreach_p->begin()) i = foreach_p->begin(); \
i != foreach_p->end(); \
++i)
#endif
////////////////////////////////////////////////////////////////////////////////

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,27 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright 2006 - 2008, Paul Beckingham. All rights reserved.
// task - a command line task list manager.
//
// Copyright 2006 - 2008, Paul Beckingham.
// All rights reserved.
//
// This program is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free Software
// Foundation; either version 2 of the License, or (at your option) any later
// version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
// details.
//
// You should have received a copy of the GNU General Public License along with
// this program; if not, write to the
//
// Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor,
// Boston, MA
// 02110-1301
// USA
//
////////////////////////////////////////////////////////////////////////////////
@@ -13,16 +34,23 @@
#include "color.h"
#include "TDB.h"
#include "T.h"
#include "stlmacros.h"
#include "../auto.h"
#ifndef max
#define max(a,b) ((a) > (b) ? (a) : (b))
#endif
#define foreach(i, c) \
for (typeof (c) *foreach_p = & (c); \
foreach_p; \
foreach_p = 0) \
for (typeof (foreach_p->begin()) i = foreach_p->begin(); \
i != foreach_p->end(); \
++i)
// parse.cpp
void parse (std::vector <std::string>&, std::string&, T&);
bool validDate (std::string&);
void parse (std::vector <std::string>&, std::string&, T&, Config&);
bool validDate (std::string&, Config&);
// task.cpp
void handleAdd (const TDB&, T&, Config&);
@@ -47,6 +75,7 @@ void handleDelete (const TDB&, T&, Config&);
void handleStart (const TDB&, T&, Config&);
void handleDone (const TDB&, T&, Config&);
void handleModify (const TDB&, T&, Config&);
void handleColor (Config&);
void gatherNextTasks (const TDB&, T&, Config&, std::vector <T>&, std::vector <int>&);
void nag (const TDB&, T&, Config&);
@@ -56,9 +85,6 @@ void wrapText (std::vector <std::string>&, const std::string&, const int);
std::string trimLeft (const std::string& in, const std::string& t = " ");
std::string trimRight (const std::string& in, const std::string& t = " ");
std::string trim (const std::string& in, const std::string& t = " ");
std::wstring trimLeft (const std::wstring& in, const std::wstring& t = L" "); // UNICODE safe
std::wstring trimRight (const std::wstring& in, const std::wstring& t = L" "); // UNICODE safe
std::wstring trim (const std::wstring& in, const std::wstring& t = L" "); // UNICODE safe
void extractParagraphs (const std::string&, std::vector<std::string>&);
void extractLine (std::string&, std::string&, int);
void split (std::vector<std::string>&, const std::string&, const char);
@@ -71,6 +97,7 @@ int autoComplete (const std::string&, const std::vector<std::string>&, std::vect
void formatTimeDeltaDays (std::string&, time_t);
std::string formatSeconds (time_t);
const std::string uuid ();
const char* optionalBlankLine (Config&);
// rules.cpp
void initializeColorRules (Config&);

View File

@@ -1,5 +1,6 @@
t.t
tdb.t
date.t
pending.data
completed.data

View File

@@ -1,6 +1,7 @@
PROJECT = t.t tdb.t
CFLAGS = -I.. -I../../../library/include -Wall -pedantic -ggdb3 -fno-rtti
LFLAGS = -L/usr/local/lib -L../../../library/lib -lcompany -lpcre -lncurses -lcurl
PROJECT = t.t tdb.t date.t
CFLAGS = -I. -I.. -Wall -pedantic -ggdb3 -fno-rtti
LFLAGS = -L/usr/local/lib
OBJECTS = ../TDB.o ../T.o ../parse.o ../text.o ../Date.o ../util.o ../Config.o
all: $(PROJECT)
@@ -16,9 +17,12 @@ clean:
.cpp.o:
g++ -c $(CFLAGS) $<
t.t: t.t.o ../T.o ../parse.o ../../../library/lib/libcompany.a
g++ t.t.o ../T.o ../parse.o $(LFLAGS) -o t.t
t.t: t.t.o $(OBJECTS) test.o
g++ t.t.o $(OBJECTS) test.o $(LFLAGS) -o t.t
tdb.t: tdb.t.o ../TDB.o ../T.o ../parse.o ../../../library/lib/libcompany.a
g++ tdb.t.o ../TDB.o ../T.o ../parse.o $(LFLAGS) -o tdb.t
tdb.t: tdb.t.o $(OBJECTS) test.o
g++ tdb.t.o $(OBJECTS) test.o $(LFLAGS) -o tdb.t
date.t: date.t.o $(OBJECTS) test.o
g++ date.t.o $(OBJECTS) test.o $(LFLAGS) -o date.t

113
src/tests/date.t.cpp Normal file
View File

@@ -0,0 +1,113 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright 2005 - 2008, Paul Beckingham. All rights reserved.
//
////////////////////////////////////////////////////////////////////////////////
#include <iostream>
#include <Date.h>
#include <test.h>
////////////////////////////////////////////////////////////////////////////////
int main (int argc, char** argv)
{
plan (63);
Date now;
Date yesterday;
yesterday -= 1;
ok (yesterday <= now, "yesterday <= now");
ok (yesterday < now, "yesterday < now");
notok (yesterday == now, "!(yesterday == now)");
ok (yesterday != now, "yesterday != now");
ok (now >= yesterday, "now >= yesterday");
ok (now > yesterday, "now > yesterday");
ok (Date::valid (2, 29, 2008), "valid: 2/29/2008");
notok (Date::valid (2, 29, 2007), "invalid: 2/29/2007");
ok (Date::leapYear (2008), "2008 is a leap year");
notok (Date::leapYear (2007), "2007 is not a leap year");
ok (Date::leapYear (2000), "2000 is a leap year");
ok (Date::leapYear (1900), "1900 is a leap year");
is (Date::daysInMonth (2, 2008), 29, "29 days in February 2008");
is (Date::daysInMonth (2, 2007), 28, "28 days in February 2007");
is (Date::monthName (1), "January", "1 = January");
is (Date::monthName (2), "February", "2 = February");
is (Date::monthName (3), "March", "3 = March");
is (Date::monthName (4), "April", "4 = April");
is (Date::monthName (5), "May", "5 = May");
is (Date::monthName (6), "June", "6 = June");
is (Date::monthName (7), "July", "7 = July");
is (Date::monthName (8), "August", "8 = August");
is (Date::monthName (9), "September", "9 = September");
is (Date::monthName (10), "October", "10 = October");
is (Date::monthName (11), "November", "11 = November");
is (Date::monthName (12), "December", "12 = December");
is (Date::dayName (0), "Sunday", "0 == Sunday");
is (Date::dayName (1), "Monday", "1 == Monday");
is (Date::dayName (2), "Tuesday", "2 == Tuesday");
is (Date::dayName (3), "Wednesday", "3 == Wednesday");
is (Date::dayName (4), "Thursday", "4 == Thursday");
is (Date::dayName (5), "Friday", "5 == Friday");
is (Date::dayName (6), "Saturday", "6 == Saturday");
Date happyNewYear (1, 1, 2008);
is (happyNewYear.dayOfWeek (), 2, "1/1/2008 == Tuesday");
is (happyNewYear.month (), 1, "1/1/2008 == January");
is (happyNewYear.day (), 1, "1/1/2008 == 1");
is (happyNewYear.year (), 2008, "1/1/2008 == 2008");
is (now - yesterday, 1, "today - yesterday == 1");
is (happyNewYear.toString (), "1/1/2008", "toString 1/1/2008");
int m, d, y;
happyNewYear.toMDY (m, d, y);
is (m, 1, "1/1/2008 == January");
is (d, 1, "1/1/2008 == 1");
is (y, 2008, "1/1/2008 == 2008");
Date epoch (9, 8, 2001);
ok ((int)epoch.toEpoch () < 1000000000, "9/8/2001 < 1,000,000,000");
epoch += 86400;
ok ((int)epoch.toEpoch () > 1000000000, "9/9/2001 > 1,000,000,000");
Date fromEpoch (epoch.toEpoch ());
is (fromEpoch.toString (), epoch.toString (), "ctor (time_t)");
Date fromString1 ("1/1/2008");
is (fromString1.month (), 1, "ctor (std::string) -> m");
is (fromString1.day (), 1, "ctor (std::string) -> d");
is (fromString1.year (), 2008, "ctor (std::string) -> y");
Date fromString2 ("1/1/2008", "m/d/Y");
is (fromString2.month (), 1, "ctor (std::string) -> m");
is (fromString2.day (), 1, "ctor (std::string) -> d");
is (fromString2.year (), 2008, "ctor (std::string) -> y");
Date fromString3 ("20080101", "YMD");
is (fromString3.month (), 1, "ctor (std::string) -> m");
is (fromString3.day (), 1, "ctor (std::string) -> d");
is (fromString3.year (), 2008, "ctor (std::string) -> y");
Date fromString4 ("12/31/2007");
is (fromString4.month (), 12, "ctor (std::string) -> m");
is (fromString4.day (), 31, "ctor (std::string) -> d");
is (fromString4.year (), 2007, "ctor (std::string) -> y");
Date fromString5 ("12/31/2007", "m/d/Y");
is (fromString5.month (), 12, "ctor (std::string) -> m");
is (fromString5.day (), 31, "ctor (std::string) -> d");
is (fromString5.year (), 2007, "ctor (std::string) -> y");
Date fromString6 ("20071231", "YMD");
is (fromString6.month (), 12, "ctor (std::string) -> m");
is (fromString6.day (), 31, "ctor (std::string) -> d");
is (fromString6.year (), 2007, "ctor (std::string) -> y");
return 0;
}
////////////////////////////////////////////////////////////////////////////////

View File

@@ -1,8 +1,32 @@
////////////////////////////////////////////////////////////////////////////////
// task - a command line task list manager.
//
// Copyright 2006 - 2008, Paul Beckingham.
// All rights reserved.
//
// This program is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free Software
// Foundation; either version 2 of the License, or (at your option) any later
// version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
// details.
//
// You should have received a copy of the GNU General Public License along with
// this program; if not, write to the
//
// Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor,
// Boston, MA
// 02110-1301
// USA
//
////////////////////////////////////////////////////////////////////////////////
#include <T.h>
#include <library.h>
#include "../T.h"
#include "../task.h"
#include "test.h"
////////////////////////////////////////////////////////////////////////////////
int main (int argc, char** argv)

View File

@@ -1,11 +1,35 @@
////////////////////////////////////////////////////////////////////////////////
// task - a command line task list manager.
//
// Copyright 2006 - 2008, Paul Beckingham.
// All rights reserved.
//
// This program is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free Software
// Foundation; either version 2 of the License, or (at your option) any later
// version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
// details.
//
// You should have received a copy of the GNU General Public License along with
// this program; if not, write to the
//
// Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor,
// Boston, MA
// 02110-1301
// USA
//
////////////////////////////////////////////////////////////////////////////////
#include <iostream>
#include <unistd.h>
#include <TDB.h>
#include <library.h>
#include "../TDB.h"
#include "../task.h"
#include "test.h"
////////////////////////////////////////////////////////////////////////////////
int main (int argc, char** argv)
@@ -116,10 +140,10 @@ int main (int argc, char** argv)
return -2;
}
/*
unlink ("./pending.data");
unlink ("./completed.data");
*/
return 0;
}

275
src/tests/test.cpp Normal file
View File

@@ -0,0 +1,275 @@
////////////////////////////////////////////////////////////////////////////////
// task - a command line task list manager.
//
// Copyright 2006 - 2008, Paul Beckingham.
// All rights reserved.
//
// This program is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free Software
// Foundation; either version 2 of the License, or (at your option) any later
// version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
// details.
//
// You should have received a copy of the GNU General Public License along with
// this program; if not, write to the
//
// Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor,
// Boston, MA
// 02110-1301
// USA
//
////////////////////////////////////////////////////////////////////////////////
#include <iostream>
#include <string>
#include <task.h>
static int total = 0;
static int counter = 0;
///////////////////////////////////////////////////////////////////////////////
static void check (void)
{
if (counter > total)
std::cout << "# Warning: There are more tests than planned."
<< std::endl;
}
///////////////////////////////////////////////////////////////////////////////
void plan (int quantity)
{
total = quantity;
std::cout << "1.." << quantity << std::endl;
check ();
}
///////////////////////////////////////////////////////////////////////////////
void ok (bool expression, const std::string& name)
{
++counter;
if (expression)
std::cout << "ok "
<< counter
<< " - "
<< name
<< std::endl;
else
std::cout << "not ok "
<< counter
<< " - "
<< name
<< std::endl;
check ();
}
///////////////////////////////////////////////////////////////////////////////
void notok (bool expression, const std::string& name)
{
++counter;
if (!expression)
std::cout << "ok "
<< counter
<< " - "
<< name
<< std::endl;
else
std::cout << "not ok "
<< counter
<< " - "
<< name
<< std::endl;
check ();
}
///////////////////////////////////////////////////////////////////////////////
void is (bool actual, bool expected, const std::string& name)
{
++counter;
if (actual == expected)
std::cout << "ok "
<< counter
<< " - "
<< name
<< std::endl;
else
std::cout << "not ok "
<< counter
<< " - "
<< name
<< std::endl
<< "# expected: "
<< expected
<< std::endl
<< "# got: "
<< actual
<< std::endl;
check ();
}
///////////////////////////////////////////////////////////////////////////////
void is (size_t actual, size_t expected, const std::string& name)
{
++counter;
if (actual == expected)
std::cout << "ok "
<< counter
<< " - "
<< name
<< std::endl;
else
std::cout << "not ok "
<< counter
<< " - "
<< name
<< std::endl
<< "# expected: "
<< expected
<< std::endl
<< "# got: "
<< actual
<< std::endl;
check ();
}
///////////////////////////////////////////////////////////////////////////////
void is (int actual, int expected, const std::string& name)
{
++counter;
if (actual == expected)
std::cout << "ok "
<< counter
<< " - "
<< name
<< std::endl;
else
std::cout << "not ok "
<< counter
<< " - "
<< name
<< std::endl
<< "# expected: "
<< expected
<< std::endl
<< "# got: "
<< actual
<< std::endl;
check ();
}
///////////////////////////////////////////////////////////////////////////////
void is (double actual, double expected, const std::string& name)
{
++counter;
if (actual == expected)
std::cout << "ok "
<< counter
<< " - "
<< name
<< std::endl;
else
std::cout << "not ok "
<< counter
<< " - "
<< name
<< std::endl
<< "# expected: "
<< expected
<< std::endl
<< "# got: "
<< actual
<< std::endl;
check ();
}
///////////////////////////////////////////////////////////////////////////////
void is (char actual, char expected, const std::string& name)
{
++counter;
if (actual == expected)
std::cout << "ok "
<< counter
<< " - "
<< name
<< std::endl;
else
std::cout << "not ok "
<< counter
<< " - "
<< name
<< std::endl
<< "# expected: "
<< expected
<< std::endl
<< "# got: "
<< actual
<< std::endl;
check ();
}
///////////////////////////////////////////////////////////////////////////////
void is (
const std::string& actual,
const std::string& expected,
const std::string& name)
{
++counter;
if (actual == expected)
std::cout << "ok "
<< counter
<< " - "
<< name
<< std::endl;
else
std::cout << "not ok "
<< counter
<< " - "
<< name
<< std::endl
<< "# expected: '"
<< expected
<< "'"
<< std::endl
<< "# got: '"
<< actual
<< "'"
<< std::endl;
check ();
}
///////////////////////////////////////////////////////////////////////////////
void diag (const std::string& text)
{
std::string trimmed = trim (text, " \t\n\r\f");
std::cout << "# " << trimmed << std::endl;
}
///////////////////////////////////////////////////////////////////////////////
void pass (const std::string& text)
{
++counter;
std::cout << "ok "
<< counter
<< " "
<< text
<< std::endl;
}
///////////////////////////////////////////////////////////////////////////////
void fail (const std::string& text)
{
++counter;
std::cout << "not ok "
<< counter
<< " "
<< text
<< std::endl;
}
///////////////////////////////////////////////////////////////////////////////

46
src/tests/test.h Normal file
View File

@@ -0,0 +1,46 @@
////////////////////////////////////////////////////////////////////////////////
// task - a command line task list manager.
//
// Copyright 2006 - 2008, Paul Beckingham.
// All rights reserved.
//
// This program is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free Software
// Foundation; either version 2 of the License, or (at your option) any later
// version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
// details.
//
// You should have received a copy of the GNU General Public License along with
// this program; if not, write to the
//
// Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor,
// Boston, MA
// 02110-1301
// USA
//
////////////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_TEST
#define INCLUDED_TEST
#include <string>
void plan (int);
void ok (bool, const std::string&);
void notok (bool, const std::string&);
void is (bool, bool, const std::string&);
void is (int, int, const std::string&);
void is (size_t, size_t, const std::string&);
void is (double, double, const std::string&);
void is (char, char, const std::string&);
void is (const std::string&, const std::string&, const std::string&);
void diag (const std::string&);
void fail (const std::string&);
void pass (const std::string&);
#endif
////////////////////////////////////////////////////////////////////////////////

View File

@@ -1,6 +1,27 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright 2004 - 2008, Paul Beckingham. All rights reserved.
// task - a command line task list manager.
//
// Copyright 2006 - 2008, Paul Beckingham.
// All rights reserved.
//
// This program is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free Software
// Foundation; either version 2 of the License, or (at your option) any later
// version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
// details.
//
// You should have received a copy of the GNU General Public License along with
// this program; if not, write to the
//
// Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor,
// Boston, MA
// 02110-1301
// USA
//
////////////////////////////////////////////////////////////////////////////////
#include <iostream>
@@ -8,6 +29,9 @@
#include <string>
#include "task.h"
static const char* newline = "\n";
static const char* noline = "";
///////////////////////////////////////////////////////////////////////////////
void wrapText (
std::vector <std::string>& lines,
@@ -76,8 +100,8 @@ void extractParagraphs (const std::string& input, std::vector<std::string>& outp
std::string copy = input;
while (1)
{
unsigned int so = copy.find ("<p>");
unsigned int eo = copy.find ("</p>");
size_t so = copy.find ("<p>");
size_t eo = copy.find ("</p>");
if (so == std::string::npos && eo == std::string::npos)
break;
@@ -99,13 +123,6 @@ std::string trimLeft (const std::string& in, const std::string& t /*= " "*/)
return out.erase (0, in.find_first_not_of (t));
}
// UNICODE safe
std::wstring trimLeft (const std::wstring& in, const std::wstring& t /*= L" "*/)
{
std::wstring out = in;
return out.erase (0, in.find_first_not_of (t));
}
////////////////////////////////////////////////////////////////////////////////
std::string trimRight (const std::string& in, const std::string& t /*= " "*/)
{
@@ -113,13 +130,6 @@ std::string trimRight (const std::string& in, const std::string& t /*= " "*/)
return out.erase (out.find_last_not_of (t) + 1);
}
// UNICODE safe
std::wstring trimRight (const std::wstring& in, const std::wstring& t /*= L" "*/)
{
std::wstring out = in;
return out.erase (out.find_last_not_of (t) + 1);
}
////////////////////////////////////////////////////////////////////////////////
std::string trim (const std::string& in, const std::string& t /*= " "*/)
{
@@ -127,13 +137,6 @@ std::string trim (const std::string& in, const std::string& t /*= " "*/)
return trimLeft (trimRight (out, t), t);
}
// UNICODE safe
std::wstring trim (const std::wstring& in, const std::wstring& t /*= L" "*/)
{
std::wstring out = in;
return trimLeft (trimRight (out, t), t);
}
////////////////////////////////////////////////////////////////////////////////
// Remove enclosing balanced quotes. Assumes trimmed text.
void unquoteText (std::string& text)
@@ -147,7 +150,7 @@ void unquoteText (std::string& text)
////////////////////////////////////////////////////////////////////////////////
void extractLine (std::string& text, std::string& line, int length)
{
unsigned int eol = text.find ("\n");
size_t eol = text.find ("\n");
// Special case: found \n in first length characters.
if (eol != std::string::npos && eol < (unsigned) length)
@@ -183,8 +186,16 @@ void extractLine (std::string& text, std::string& line, int length)
// If no space was found, hyphenate.
else
{
line = text.substr (0, length - 1) + "-";
text = text.substr (length - 1, std::string::npos);
if (length > 1)
{
line = text.substr (0, length - 1) + "-";
text = text.substr (length - 1, std::string::npos);
}
else
{
line = text.substr (0, 1);
text = text.substr (length, std::string::npos);
}
}
}
@@ -275,3 +286,12 @@ std::string lowerCase (const std::string& input)
}
////////////////////////////////////////////////////////////////////////////////
const char* optionalBlankLine (Config& conf)
{
if (conf.get ("blanklines", true) == true)
return newline;
return noline;
}
////////////////////////////////////////////////////////////////////////////////

View File

@@ -1,6 +1,27 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright 2006 - 2008, Paul Beckingham. All rights reserved.
// task - a command line task list manager.
//
// Copyright 2006 - 2008, Paul Beckingham.
// All rights reserved.
//
// This program is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free Software
// Foundation; either version 2 of the License, or (at your option) any later
// version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
// details.
//
// You should have received a copy of the GNU General Public License along with
// this program; if not, write to the
//
// Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor,
// Boston, MA
// 02110-1301
// USA
//
////////////////////////////////////////////////////////////////////////////////
#include <iostream>
@@ -10,6 +31,7 @@
#include <sys/time.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include "Table.h"
#include "task.h"
#include "../auto.h"
@@ -160,14 +182,18 @@ const std::string uuid ()
static char randomHexDigit ()
{
static char digits[] = "0123456789abcdef";
#ifdef HAVE_RANDOM
return digits[random () % 16];
#else
return digits[rand () % 16];
#endif
}
////////////////////////////////////////////////////////////////////////////////
const std::string uuid ()
{
// xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
char id [37];
char id [48] = {0};
id[0] = randomHexDigit ();
id[1] = randomHexDigit ();
id[2] = randomHexDigit ();

1227
task.html Normal file

File diff suppressed because it is too large Load Diff