Compare commits

...

43 Commits

Author SHA1 Message Date
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
48 changed files with 2384 additions and 1080 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

View File

@@ -0,0 +1,7 @@
Principal Author
Paul Beckingham, paul@beckingham.net
Contributing Authors
Testers

151
ChangeLog
View File

@@ -1,16 +1,149 @@
1.1.0 (?)
- Command line specification of .taskrc file
0.9.2
4/3/2008
- Configure now detects ncurses, flock.
1.0.0 (?)
- New movie made, uploaded
- Bug: assertion fails on mobile for t v
- Bug: configure.ac does not properly determine ncurses availability
- Bug: when run without arguments, task dumps core on Solaris 10
- 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
------ reality -----------------------------------
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
0.9.9 (5/27/2008)
+ Autoconf/autmake 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.0
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
[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 patches to task@beckingham.net

View File

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

30
NEWS
View File

@@ -1,4 +1,32 @@
Welcome to Task 1.0.0.
Task 1.0 is released.
Task has been built and tested on the following configurations:
- OS X 10.5 Leopard
- Fedora Core 8
- Fedora Core 9
- Ubuntu 8
Known Issues:
- problems running on Solaris 10
While Task has undergone testing, bugs are sure to remain. If you encounter a
bug, please contact me at bugs@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 bugs@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.

47
README
View File

@@ -1,7 +1,44 @@
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
- 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=????????????
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!

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

554
TUTORIAL
View File

@@ -1,9 +1,18 @@
Task program tutorial, for version 0.9.0
Task program tutorial, for version 1.0.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,10 +21,10 @@ 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.0.0.tar.gz
% gunzip task-1.0.0.tar.gz
% tar xf task-1.0.0.tar
% cd task-1.0.0
% ./configure
...
% make
@@ -23,21 +32,24 @@ transcript illustrates a typical installation:
% make install
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
@@ -70,14 +82,15 @@ 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
@@ -92,9 +105,10 @@ 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.
Now that projects are assigned, we can look at just the Wedding project tasks:
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. Now that projects are assigned, we can look at just the Wedding
project tasks:
% task ls project:Wedding
@@ -136,37 +150,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
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 +199,451 @@ 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:
Valid background colors are:
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.
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
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

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, 0.9.9, 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.
@@ -37,5 +36,5 @@ 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_CONFIG_FILES([Makefile])
AC_CONFIG_FILES([Makefile src/Makefile])
AC_OUTPUT

68
script.txt Normal file
View File

@@ -0,0 +1,68 @@
task add do laundry
task add project:garage order dumpster
task add +phone tell mom i loveher
task add +phone pro:garage schedule goodwill pickup
task add +email pro:garage ask Tom if he wants that old bike
task ls
task 1 pro:home
task 3 pro:home tell mom I love her
task ls pro:garage
task long pro:garage
task list pro:garage
task lis +phone
task li pro:garage +phone
task l mom
task 1 priority:H
task pri:H 3
task 1 pri:M
task li
task 2 pri:L
task li
task do 3
task li
# There may be an arbitrary number of tags.
task 2 +phone +mistake
# Oops!
task 2 -mistake
task tags
task info 2
task projects
task 3 fg:bold
task li
task 3 fg:white
task li
task 3 fg:bold_underline_white
task li
task 4 bg:on_bright_red fg:bold_yellow
task li
task 4 bg:
task li
task 4 fg:
task colors
task 1 due:6/8/2008
task li
task calendar
task 1 due:6/1/2008
task li
task overdue
task cal
task export file.csv
cat file.csv
task start 1
task active
task do 1
task li
task do 3
task do 1
task active
task summary
task history

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 stlmacros.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,6 +394,10 @@ Table.h:
color.h:
Grid.h:
color.h:
TDB.h:
T.h:

View File

@@ -95,7 +95,8 @@ 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 stlmacros.h ../auto.h \
Date.h
/usr/include/c++/4.0.0/iostream:
@@ -379,6 +380,10 @@ Table.h:
color.h:
Grid.h:
color.h:
TDB.h:
T.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 stlmacros.h ../auto.h
/usr/include/c++/4.0.0/iostream:
@@ -379,6 +379,10 @@ Table.h:
color.h:
Grid.h:
color.h:
TDB.h:
T.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 stlmacros.h ../auto.h
/usr/include/c++/4.0.0/iostream:
@@ -395,6 +395,10 @@ Table.h:
color.h:
Grid.h:
color.h:
TDB.h:
T.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 \
stlmacros.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,16 @@ task.h:
Config.h:
Table.h:
color.h:
TDB.h:
T.h:
T.h:
stlmacros.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 stlmacros.h ../auto.h
/usr/include/c++/4.0.0/iostream:
@@ -382,6 +382,10 @@ Table.h:
color.h:
Grid.h:
color.h:
TDB.h:
T.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 stlmacros.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,6 +385,8 @@ task.h:
/usr/include/sys/types.h:
color.h:
TDB.h:
stlmacros.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 \
stlmacros.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,6 +396,8 @@ Table.h:
color.h:
Grid.h:
stlmacros.h:
TDB.h:
@@ -404,6 +406,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 stlmacros.h ../auto.h
/usr/include/c++/4.0.0/iostream:
@@ -379,6 +379,10 @@ Table.h:
color.h:
Grid.h:
color.h:
TDB.h:
T.h:

View File

@@ -95,8 +95,9 @@ 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 stlmacros.h ../auto.h \
/usr/include/uuid/uuid.h
/usr/include/c++/4.0.0/iostream:
@@ -378,10 +379,14 @@ Table.h:
color.h:
Grid.h:
task.h:
Config.h:
color.h:
TDB.h:
T.h:

2
src/.gitignore vendored Normal file
View File

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

View File

@@ -6,6 +6,8 @@
#include <iostream>
#include <fstream>
#include <sstream>
#include <sys/stat.h>
#include <stdlib.h>
#include "task.h"
#include "Config.h"
@@ -34,7 +36,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 +45,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 +62,67 @@ 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 != "")
{
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");
fclose (out);
set ("data.location", taskDir);
set ("command.logging", "off");
set ("confirmation", "yes");
set ("next", 2);
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

@@ -17,6 +17,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

@@ -5,6 +5,8 @@
////////////////////////////////////////////////////////////////////////////////
#include <iostream>
#include <time.h>
#include <assert.h>
#include <stdlib.h>
#include "task.h"
#include "Date.h"
@@ -36,8 +38,8 @@ Date::Date (const int m, const int d, const int y)
////////////////////////////////////////////////////////////////////////////////
Date::Date (const std::string& mdy)
{
unsigned int firstSlash = mdy.find ("/");
unsigned int secondSlash = mdy.find ("/", firstSlash + 1);
size_t firstSlash = mdy.find ("/");
size_t secondSlash = mdy.find ("/", firstSlash + 1);
if (firstSlash != std::string::npos &&
secondSlash != std::string::npos)
{
@@ -155,7 +157,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 +181,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 +198,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",

429
src/Grid.cpp Normal file
View File

@@ -0,0 +1,429 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright 2007 - 2008, Paul Beckingham. All rights reserved.
//
// 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)
// {
// std::cout << "additional mRows[" << r << "] = NULL" << std::endl;
mRows.push_back (NULL);
// }
else
// {
// std::cout << "additional mRows[" << r << "] = new std::vector <Cell*>" << std::endl;
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)
// {
// std::cout << "existing mRows[" << row << "] = new std::vector <Cell*>" << std::endl;
mRows[row] = new std::vector <Cell*>;
// }
if (col >= mRows[row]->size ())
for (unsigned int c = mRows[row]->size (); c <= col; ++c)
// {
// std::cout << "additional mRows[" << row << "][" << c << "] = NULL" << std::endl;
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)
// {
// std::cout << "additional mColumns[" << c << "] = NULL" << std::endl;
mColumns.push_back (NULL);
// }
else
// {
// std::cout << "additional mColumns[" << c << "] = new std::vector <Cell*>" << std::endl;
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)
// {
// std::cout << "existing mColumns[" << col << "] = new std::vector <Cell*>" << std::endl;
mColumns[col] = new std::vector <Cell*>;
// }
if (row >= mColumns[col]->size ())
for (unsigned int r = mColumns[col]->size (); r <= row; ++r)
// {
// std::cout << "additional mColumns[" << col << "][" << r << "] = NULL" << std::endl;
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)
// {
// std::cout << "deleted old cell mRows[" << row << "][" << col << "]" << std::endl;
delete (*mRows[row])[col];
// }
(*mRows[row])[col] = cell;
(*mColumns[col])[row] = cell;
// std::cout << "assigned new cell mRows[" << row << "][" << col << "]" << std::endl;
// std::cout << "assigned new cell mColumns[" << col << "][" << row << "]" << std::endl;
}
////////////////////////////////////////////////////////////////////////////////
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;
}
////////////////////////////////////////////////////////////////////////////////

78
src/Grid.h Normal file
View File

@@ -0,0 +1,78 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright 2007 - 2008, Paul Beckingham. All rights reserved.
//
//
////////////////////////////////////////////////////////////////////////////////
#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 stlmacros.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 stlmacros.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

@@ -115,7 +115,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 +137,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 +242,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];
@@ -297,7 +297,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 +364,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 +383,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 +415,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 +434,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 +500,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 +508,4 @@ int T::determineVersion (const std::string& line)
return 0;
}
////////////////////////////////////////////////////////////////////////////////

View File

@@ -7,6 +7,7 @@
#include <fstream>
#include <sys/file.h>
#include <unistd.h>
#include <string.h>
#include "task.h"
#include "TDB.h"

View File

@@ -22,10 +22,12 @@
//
////////////////////////////////////////////////////////////////////////////////
#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>
#include <stlmacros.h>
////////////////////////////////////////////////////////////////////////////////
Table::Table ()
@@ -45,20 +47,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 +99,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 +108,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 +116,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 +155,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 +172,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 +211,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 +228,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 +346,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 +381,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 +417,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 +442,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 +464,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 +478,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 +495,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 +506,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 +532,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 +557,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 +580,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 +595,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 +616,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,19 +629,15 @@ void Table::formatCell (
for (int i = 0; i < width; ++i)
pad += " ";
blank =
colorOn +
pad +
intraPad +
colorOff;
blank = Text::colorize (fg, bg, pad + intraPad);
}
////////////////////////////////////////////////////////////////////////////////
const std::string Table::formatCell (
int row,
int col,
int width,
int padding)
const int row,
const int col,
const int width,
const int padding)
{
assert (width > 0);
@@ -730,29 +646,10 @@ const std::string Table::formatCell (
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 += " ";
@@ -775,7 +672,7 @@ const std::string 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 += " ";
}
@@ -783,14 +680,7 @@ const std::string Table::formatCell (
for (int i = 0; i < getIntraPadding (); ++i)
intraPad += " ";
return colorOn +
pad +
preJust +
data +
postJust +
pad +
intraPad +
colorOff;
return Text::colorize (fg, bg, pad + preJust + data + postJust + pad + intraPad);
}
////////////////////////////////////////////////////////////////////////////////
@@ -826,7 +716,7 @@ void Table::optimize (std::string& output)
*/
// \s\n -> \n
unsigned int i = 0;
size_t i = 0;
while ((i = output.find (" \n")) != std::string::npos)
{
output = output.substr (0, i) +
@@ -869,52 +759,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);
Date dr ((std::string)*right);
if (dl > dr)
SWAP
}
@@ -923,16 +812,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);
Date dr ((std::string)*right);
if (dl < dr)
SWAP
}
@@ -940,16 +829,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 +857,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 +886,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 +909,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 +930,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

@@ -10,7 +10,8 @@
#include <map>
#include <vector>
#include <string>
#include "color.h"
#include <color.h>
#include <Grid.h>
class Table
{
@@ -64,20 +65,20 @@ public:
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);
const std::string formatCell (const int, 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 +87,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,9 +101,9 @@ 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;

View File

@@ -7,58 +7,234 @@
#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

@@ -8,14 +8,27 @@
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

@@ -4,6 +4,7 @@
//
////////////////////////////////////////////////////////////////////////////////
#include <iostream>
#include <stdlib.h>
#include <string>
#include <vector>
#include <map>
@@ -13,20 +14,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 +89,12 @@ static char* attributes[] =
"",
};
static char* commands[] =
static const char* commands[] =
{
"active",
"add",
"calendar",
"colors",
"completed",
"delete",
"done",
@@ -65,7 +116,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 +137,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 += ", ";
@@ -115,8 +166,8 @@ static bool isCommand (const std::string& candidate)
////////////////////////////////////////////////////////////////////////////////
bool validDate (std::string& date)
{
unsigned int firstSlash = date.find ("/");
unsigned int secondSlash = date.find ("/", firstSlash + 1);
size_t firstSlash = date.find ("/");
size_t secondSlash = date.find ("/", firstSlash + 1);
if (firstSlash != std::string::npos &&
secondSlash != std::string::npos)
{
@@ -186,7 +237,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 +276,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 &&
@@ -268,10 +319,10 @@ void parse (
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;

View File

@@ -4,6 +4,7 @@
//
////////////////////////////////////////////////////////////////////////////////
#include <iostream>
#include <stdlib.h>
#include "Config.h"
#include "Table.h"
#include "Date.h"
@@ -16,8 +17,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 +26,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 +61,7 @@ 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.
// Colorization of the tagged.
if (gsFg["color.tagged"] != Text::nocolor ||

View File

@@ -1,5 +1,5 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright 2006 - 2008 Paul Beckingham.
// Copyright 2006 - 2008, Paul Beckingham.
// All rights reserved.
//
//
@@ -9,6 +9,7 @@
#include <fstream>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <pwd.h>
#include <time.h>
@@ -38,9 +39,9 @@ void usage (Config& conf)
}
#endif
table.addColumn ("");
table.addColumn ("");
table.addColumn ("");
table.addColumn (" ");
table.addColumn (" ");
table.addColumn (" ");
table.setColumnJustification (0, Table::left);
table.setColumnJustification (1, Table::left);
@@ -56,32 +57,32 @@ void usage (Config& conf)
table.addCell (row, 1, "task");
row = table.addRow ();
table.addCell (row, 1, "task add [tags] [attributes] description...");
table.addCell (row, 1, "task add [tags] [attrs] desc...");
table.addCell (row, 2, "Adds a new task");
row = table.addRow ();
table.addCell (row, 1, "task list [tags] [attributes] description...");
table.addCell (row, 1, "task list [tags] [attrs] desc...");
table.addCell (row, 2, "Lists all tasks matching the specified criteria");
row = table.addRow ();
table.addCell (row, 1, "task long [tags] [attributes] description...");
table.addCell (row, 1, "task long [tags] [attrs] desc...");
table.addCell (row, 2, "Lists all task, all data, matching the specified criteria");
row = table.addRow ();
table.addCell (row, 1, "task ls [tags] [attributes] description...");
table.addCell (row, 1, "task ls [tags] [attrs] desc...");
table.addCell (row, 2, "Minimal listing of all tasks matching the specified criteria");
row = table.addRow ();
table.addCell (row, 1, "task completed [tags] [attributes] description...");
table.addCell (row, 1, "task completed [tags] [attrs] desc...");
table.addCell (row, 2, "Chronological listing of all completed tasks matching the specified criteria");
row = table.addRow ();
table.addCell (row, 1, "task ID [tags] [attributes] [description...]");
table.addCell (row, 1, "task ID [tags] [attrs] [desc...]");
table.addCell (row, 2, "Modifies the existing task with provided arguments");
row = table.addRow ();
table.addCell (row, 1, "task ID /from/to/");
table.addCell (row, 2, "Perform the substitution on the description, for fixing mistakes");
table.addCell (row, 2, "Perform the substitution on the desc, for fixing mistakes");
row = table.addRow ();
table.addCell (row, 1, "task delete ID");
@@ -143,6 +144,10 @@ void usage (Config& conf)
table.addCell (row, 1, "task export");
table.addCell (row, 2, "Exports all tasks as a CSV file");
row = table.addRow ();
table.addCell (row, 1, "task color");
table.addCell (row, 2, "Displays all possible colors");
row = table.addRow ();
table.addCell (row, 1, "task version");
table.addCell (row, 2, "Shows the task version number");
@@ -180,11 +185,13 @@ void usage (Config& conf)
////////////////////////////////////////////////////////////////////////////////
int main (int argc, char** argv)
{
// TODO Find out what this is, and either promote it to live code, or remove it.
// std::set_terminate (__gnu_cxx::__verbose_terminate_handler);
try
{
// Load the config file from the home directory.
// Load the config file from the home directory. If the file cannot be
// found, offer to create a sample one.
Config conf;
struct passwd* pw = getpwuid (getuid ());
if (!pw)
@@ -192,7 +199,8 @@ int main (int argc, char** argv)
std::string home = pw->pw_dir;
home += "/.taskrc";
conf.load (home);
if (!conf.load (home))
conf.createDefault (home);
TDB tdb;
tdb.dataDirectory (conf.get ("data.location"));
@@ -217,6 +225,7 @@ int main (int argc, char** argv)
else if (command == "info") handleInfo (tdb, task, conf);
else if (command == "long") handleLongList (tdb, task, conf);
else if (command == "ls") handleSmallList (tdb, task, conf);
else if (command == "colors") handleColor ( conf);
else if (command == "completed") handleCompleted (tdb, task, conf);
else if (command == "delete") handleDelete (tdb, task, conf);
else if (command == "start") handleStart (tdb, task, conf);
@@ -492,7 +501,7 @@ void handleList (const TDB& tdb, T& task, Config& conf)
// All criteria match, so add refTask to the output table.
int row = table.addRow ();
table.addCell (row, 0, (int) i + 1);
table.addCell (row, 0, refTask.getId ());
table.addCell (row, 1, refTask.getAttribute ("project"));
table.addCell (row, 2, refTask.getAttribute ("priority"));
table.addCell (row, 3, due);
@@ -665,7 +674,7 @@ void handleSmallList (const TDB& tdb, T& task, Config& conf)
// All criteria match, so add refTask to the output table.
int row = table.addRow ();
table.addCell (row, 0, (int) i + 1);
table.addCell (row, 0, refTask.getId ());
table.addCell (row, 1, refTask.getAttribute ("project"));
table.addCell (row, 2, refTask.getAttribute ("priority"));
table.addCell (row, 3, refTask.getDescription ());
@@ -1159,7 +1168,7 @@ void handleLongList (const TDB& tdb, T& task, Config& conf)
// All criteria match, so add refTask to the output table.
int row = table.addRow ();
table.addCell (row, 0, (int) i + 1);
table.addCell (row, 0, refTask.getId ());
table.addCell (row, 1, refTask.getAttribute ("project"));
table.addCell (row, 2, refTask.getAttribute ("priority"));
table.addCell (row, 3, entered);
@@ -1686,7 +1695,7 @@ void handleReportHistory (const TDB& tdb, T& task, Config& conf)
table.setColumnJustification (4, Table::right);
table.setColumnJustification (5, Table::right);
char *months[] =
const char *months[] =
{
"January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December",
@@ -1980,7 +1989,7 @@ void handleReportActive (const TDB& tdb, T& task, Config& conf)
// All criteria match, so add refTask to the output table.
int row = table.addRow ();
table.addCell (row, 0, (int) i + 1);
table.addCell (row, 0, refTask.getId ());
table.addCell (row, 1, refTask.getAttribute ("project"));
table.addCell (row, 2, refTask.getAttribute ("priority"));
table.addCell (row, 3, due);
@@ -2099,7 +2108,7 @@ void handleReportOverdue (const TDB& tdb, T& task, Config& conf)
{
// All criteria match, so add refTask to the output table.
int row = table.addRow ();
table.addCell (row, 0, (int) i + 1);
table.addCell (row, 0, refTask.getId ());
table.addCell (row, 1, refTask.getAttribute ("project"));
table.addCell (row, 2, refTask.getAttribute ("priority"));
table.addCell (row, 3, due);
@@ -2135,17 +2144,6 @@ void handleReportOverdue (const TDB& tdb, T& task, Config& conf)
////////////////////////////////////////////////////////////////////////////////
void handleReportStats (const TDB& tdb, T& task, Config& conf)
{
// Determine window size, and set table accordingly.
int width = 80;
#ifdef HAVE_LIBNCURSES
if (conf.get ("curses", true))
{
WINDOW* w = initscr ();
width = w->_maxx + 1;
endwin ();
}
#endif
// Get all the tasks.
std::vector <T> tasks;
tdb.allT (tasks);
@@ -2350,34 +2348,38 @@ void handleDone (const TDB& tdb, T& task, Config& conf)
void handleExport (const TDB& tdb, T& task, Config& conf)
{
std::string file = trim (task.getDescription ());
std::ofstream out (file.c_str ());
if (out.good ())
if (file.length () > 0)
{
out << "'id',"
<< "'status',"
<< "'tags',"
<< "'entry',"
<< "'start',"
<< "'due',"
<< "'end',"
<< "'project',"
<< "'priority',"
<< "'fg',"
<< "'bg',"
<< "'description'"
<< "\n";
std::vector <T> all;
tdb.allT (all);
foreach (t, all)
std::ofstream out (file.c_str ());
if (out.good ())
{
out << t->composeCSV ().c_str ();
out << "'id',"
<< "'status',"
<< "'tags',"
<< "'entry',"
<< "'start',"
<< "'due',"
<< "'end',"
<< "'project',"
<< "'priority',"
<< "'fg',"
<< "'bg',"
<< "'description'"
<< "\n";
std::vector <T> all;
tdb.allT (all);
foreach (t, all)
{
out << t->composeCSV ().c_str ();
}
out.close ();
}
out.close ();
else
throw std::string ("Could not write to export file.");
}
else
throw std::string ("Could not write to export file.");
throw std::string ("You must specify a file to write to.");
}
////////////////////////////////////////////////////////////////////////////////
@@ -2446,7 +2448,7 @@ void handleModify (const TDB& tdb, T& task, Config& conf)
if (from != "")
{
std::string description = original.getDescription ();
unsigned int pattern = description.find (from);
size_t pattern = description.find (from);
if (pattern != std::string::npos)
{
description = description.substr (0, pattern) +
@@ -2470,6 +2472,83 @@ void handleModify (const TDB& tdb, T& task, Config& conf)
throw std::string ("Task not found.");
}
////////////////////////////////////////////////////////////////////////////////
void handleColor (Config& conf)
{
std::cout << std::endl << "Foreground" << std::endl
<< " "
<< Text::colorize (Text::bold, Text::nocolor, "bold") << " "
<< Text::colorize (Text::underline, Text::nocolor, "underline") << " "
<< Text::colorize (Text::bold_underline, Text::nocolor, "bold_underline") << std::endl
<< " " << Text::colorize (Text::black, Text::nocolor, "black") << " "
<< Text::colorize (Text::bold_black, Text::nocolor, "bold_black") << " "
<< Text::colorize (Text::underline_black, Text::nocolor, "underline_black") << " "
<< Text::colorize (Text::bold_underline_black, Text::nocolor, "bold_underline_black") << std::endl
<< " " << Text::colorize (Text::red, Text::nocolor, "red") << " "
<< Text::colorize (Text::bold_red, Text::nocolor, "bold_red") << " "
<< Text::colorize (Text::underline_red, Text::nocolor, "underline_red") << " "
<< Text::colorize (Text::bold_underline_red, Text::nocolor, "bold_underline_red") << std::endl
<< " " << Text::colorize (Text::green, Text::nocolor, "green") << " "
<< Text::colorize (Text::bold_green, Text::nocolor, "bold_green") << " "
<< Text::colorize (Text::underline_green, Text::nocolor, "underline_green") << " "
<< Text::colorize (Text::bold_underline_green, Text::nocolor, "bold_underline_green") << std::endl
<< " " << Text::colorize (Text::yellow, Text::nocolor, "yellow") << " "
<< Text::colorize (Text::bold_yellow, Text::nocolor, "bold_yellow") << " "
<< Text::colorize (Text::underline_yellow, Text::nocolor, "underline_yellow") << " "
<< Text::colorize (Text::bold_underline_yellow, Text::nocolor, "bold_underline_yellow") << std::endl
<< " " << Text::colorize (Text::blue, Text::nocolor, "blue") << " "
<< Text::colorize (Text::bold_blue, Text::nocolor, "bold_blue") << " "
<< Text::colorize (Text::underline_blue, Text::nocolor, "underline_blue") << " "
<< Text::colorize (Text::bold_underline_blue, Text::nocolor, "bold_underline_blue") << std::endl
<< " " << Text::colorize (Text::magenta, Text::nocolor, "magenta") << " "
<< Text::colorize (Text::bold_magenta, Text::nocolor, "bold_magenta") << " "
<< Text::colorize (Text::underline_magenta, Text::nocolor, "underline_magenta") << " "
<< Text::colorize (Text::bold_underline_magenta, Text::nocolor, "bold_underline_magenta") << std::endl
<< " " << Text::colorize (Text::cyan, Text::nocolor, "cyan") << " "
<< Text::colorize (Text::bold_cyan, Text::nocolor, "bold_cyan") << " "
<< Text::colorize (Text::underline_cyan, Text::nocolor, "underline_cyan") << " "
<< Text::colorize (Text::bold_underline_cyan, Text::nocolor, "bold_underline_cyan") << std::endl
<< " " << Text::colorize (Text::white, Text::nocolor, "white") << " "
<< Text::colorize (Text::bold_white, Text::nocolor, "bold_white") << " "
<< Text::colorize (Text::underline_white, Text::nocolor, "underline_white") << " "
<< Text::colorize (Text::bold_underline_white, Text::nocolor, "bold_underline_white") << std::endl
<< std::endl << "Background" << std::endl
<< " " << Text::colorize (Text::nocolor, Text::on_black, "on_black") << " "
<< Text::colorize (Text::nocolor, Text::on_bright_black, "on_bright_black") << std::endl
<< " " << Text::colorize (Text::nocolor, Text::on_red, "on_red") << " "
<< Text::colorize (Text::nocolor, Text::on_bright_red, "on_bright_red") << std::endl
<< " " << Text::colorize (Text::nocolor, Text::on_green, "on_green") << " "
<< Text::colorize (Text::nocolor, Text::on_bright_green, "on_bright_green") << std::endl
<< " " << Text::colorize (Text::nocolor, Text::on_yellow, "on_yellow") << " "
<< Text::colorize (Text::nocolor, Text::on_bright_yellow, "on_bright_yellow") << std::endl
<< " " << Text::colorize (Text::nocolor, Text::on_blue, "on_blue") << " "
<< Text::colorize (Text::nocolor, Text::on_bright_blue, "on_bright_blue") << std::endl
<< " " << Text::colorize (Text::nocolor, Text::on_magenta, "on_magenta") << " "
<< Text::colorize (Text::nocolor, Text::on_bright_magenta, "on_bright_magenta") << std::endl
<< " " << Text::colorize (Text::nocolor, Text::on_cyan, "on_cyan") << " "
<< Text::colorize (Text::nocolor, Text::on_bright_cyan, "on_bright_cyan") << std::endl
<< " " << Text::colorize (Text::nocolor, Text::on_white, "on_white") << " "
<< Text::colorize (Text::nocolor, Text::on_bright_white, "on_bright_white") << std::endl
<< std::endl;
}
////////////////////////////////////////////////////////////////////////////////
void gatherNextTasks (
const TDB& tdb,

View File

@@ -47,6 +47,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 +57,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);

View File

@@ -1,24 +0,0 @@
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
all: $(PROJECT)
install: $(PROJECT)
@echo unimplemented
test: $(PROJECT)
@echo unimplemented
clean:
-rm *.o $(PROJECT)
.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
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

View File

@@ -1,8 +1,9 @@
////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
#include <T.h>
#include <library.h>
#include "../T.h"
#include "../task.h"
#include "test.h"
////////////////////////////////////////////////////////////////////////////////
int main (int argc, char** argv)

View File

@@ -4,8 +4,9 @@
#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 +117,10 @@ int main (int argc, char** argv)
return -2;
}
/*
unlink ("./pending.data");
unlink ("./completed.data");
*/
return 0;
}

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

@@ -0,0 +1,254 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright 2007, 2008, Paul Beckingham. All rights reserved.
//
//
////////////////////////////////////////////////////////////////////////////////
#include <iostream>
#include <string>
#include <library.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;
}
///////////////////////////////////////////////////////////////////////////////

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

@@ -0,0 +1,24 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright 2007, 2008, Paul Beckingham. All rights reserved.
//
////////////////////////////////////////////////////////////////////////////////
#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

@@ -76,8 +76,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 +99,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 +106,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 +113,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 +126,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 +162,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);
}
}
}

View File

@@ -10,6 +10,7 @@
#include <sys/time.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include "Table.h"
#include "task.h"
#include "../auto.h"