Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bcdcbeeea0 | ||
|
|
469cafa053 | ||
|
|
fdb359c180 | ||
|
|
b3d40b2554 | ||
|
|
fba076a0d0 | ||
|
|
3ef844de5f | ||
|
|
bb45d91ddb | ||
|
|
f243f0ed44 | ||
|
|
b305cc0a60 | ||
|
|
53609b2837 | ||
|
|
bdaa0f89d9 | ||
|
|
2fd8d8aa83 | ||
|
|
e69fb81b2b | ||
|
|
d2aa0f31b0 | ||
|
|
05f67db429 | ||
|
|
62be3f8acb | ||
|
|
cc5c99c0a1 |
2
AUTHORS
2
AUTHORS
@@ -38,4 +38,4 @@ Thanks to the following, who submitted detailed bug reports and excellent sugges
|
||||
Mike Adonay
|
||||
Thomas@BIC
|
||||
Ian Mortimer
|
||||
|
||||
Zach Frazier
|
||||
|
||||
22
ChangeLog
22
ChangeLog
@@ -1,7 +1,25 @@
|
||||
|
||||
------ current release ---------------------------
|
||||
|
||||
1.8.1 (8/20/2009)
|
||||
1.8.3 (10/21/2009)
|
||||
+ Added support for Haiku R1/alpha1
|
||||
|
||||
------ old releases ------------------------------
|
||||
|
||||
1.8.2 (9/7/2009) f243f0ed443ecd7dde779de8a6525222591024db
|
||||
+ Added feature #282 that returns useful exit codes to the shell. Now a
|
||||
script can detect whether no tasks were returned by a report (thanks to
|
||||
Pietro Cerutti).
|
||||
+ Fixed bug #287 that causes color control codes to be written to shadow
|
||||
files (thanks to Richard Querin).
|
||||
+ Fixed bug #289 which imported task from todo.sh without valid uuids
|
||||
(thanks to Ben Jackson).
|
||||
+ Fixed bug #291 which generated a false warning about an unrecognized
|
||||
variable when enabling default.projects in .taskrc (thanks to Thomas@BIC).
|
||||
+ Fixed bug #288 which failed to propagate rc file overrides on the command
|
||||
line to the default command (thanks to Zach Frazier).
|
||||
|
||||
1.8.1 (8/20/2009) 35792e7874d2bb664abb1a0a67960b7fe7e0fccf
|
||||
+ Fixed bug #231 that broke the build on OpenBSD 32-bit due to a time_t
|
||||
and int collision (thanks to Pietro Cerutti).
|
||||
+ Fixed bug #241 that prevented bash's tab-completion of projects in Fedora
|
||||
@@ -34,8 +52,6 @@
|
||||
+ Fixed bug that failed to suppress color control code in the header and footnote
|
||||
when redirecting output to a file (thanks to John Florian).
|
||||
|
||||
------ old releases ------------------------------
|
||||
|
||||
1.8.0 (7/21/2009) 14977ef317bd004dae2f2c313e806af9f2a2140c
|
||||
+ Added zsh tab completion script (thanks to P.C. Shyamshankar).
|
||||
+ Fixed bug that cause the _forcecolor configuration variable to be
|
||||
|
||||
18
NEWS
18
NEWS
@@ -9,26 +9,24 @@ New Features in task 1.8
|
||||
- In addition to being a standard part of Fedora 10 and 11 (yum install task),
|
||||
task is now also a standard part of Cygwin 1.5
|
||||
- There are new demo movies on taskwarrior.org
|
||||
- Shell-friendly exit codes
|
||||
|
||||
Please refer to the ChangeLog file for full details. There are too many to
|
||||
list here.
|
||||
|
||||
Task has been built and tested on the following configurations:
|
||||
|
||||
- OS X 10.5 Leopard
|
||||
- OS X 10.4 Tiger
|
||||
- Fedora Core 11 Leonidas
|
||||
- Fedora Core 10 Cambridge
|
||||
- Ubuntu 9.04 Jaunty Jackalope
|
||||
- Ubuntu 8.10 Intrepid Ibex
|
||||
- Ubuntu 8.04 Hardy Heron
|
||||
- OS X 10.6 Snow Leopard and 10.5 Leopard
|
||||
- Fedora 11 Leonidas and 10 Cambridge
|
||||
- Ubuntu 9.04 Jaunty Jackalope and 8.10 Intrepid Ibex
|
||||
- Slackware 12.2
|
||||
- Arch Linux
|
||||
- Solaris 10
|
||||
- Solaris 8
|
||||
- Gentoo Linux
|
||||
- Solaris 10 and 8
|
||||
- OpenBSD 4.5
|
||||
- FreeBSD
|
||||
- Cygwin 1.5.25-14
|
||||
- Cygwin 1.5
|
||||
- Haiku R1/alpha1
|
||||
|
||||
While Task has undergone testing, bugs are sure to remain. If you encounter a
|
||||
bug, please enter a new issue at:
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_PREREQ(2.61)
|
||||
AC_INIT(task, 1.8.1, support@taskwarrior.org)
|
||||
AC_INIT(task, 1.8.3, support@taskwarrior.org)
|
||||
|
||||
CFLAGS="${CFLAGS=}"
|
||||
CXXFLAGS="${CXXFLAGS=}"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.TH task-tutorial 5 2009-08-14 "task 1.8.1" "User Manuals"
|
||||
.TH task-tutorial 5 2009-10-21 "task 1.8.3" "User Manuals"
|
||||
|
||||
.SH NAME
|
||||
task-tutorial \- A tutorial for the task(1) command line todo manager.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.TH task 1 2009-08-14 "task 1.8.1" "User Manuals"
|
||||
.TH task 1 2009-10-21 "task 1.8.3" "User Manuals"
|
||||
|
||||
.SH NAME
|
||||
task \- A command line todo manager.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.TH taskrc 5 2009-08-14 "task 1.8.1" "User Manuals"
|
||||
.TH taskrc 5 2009-10-21 "task 1.8.3" "User Manuals"
|
||||
|
||||
.SH NAME
|
||||
taskrc \- Configuration file for the task(1) command
|
||||
|
||||
@@ -1 +1 @@
|
||||
<pkg-contents spec="1.12"><f n="task" o="paul" g="staff" p="33261" pt="/Users/paul/task.git/package-config/osx/binary/task" m="false" t="file"/></pkg-contents>
|
||||
<pkg-contents spec="1.12"><f n="task" o="root" g="wheel" p="33261" pt="/Users/paul/task.git/package-config/osx/binary/task" m="false" t="file"><mod>group</mod><mod>owner</mod></f></pkg-contents>
|
||||
@@ -1 +1 @@
|
||||
<pkgref spec="1.12" uuid="C71026FD-E252-42CD-89C3-2F6F087AAF17"><config><identifier>com.beckingham.task180.task.pkg</identifier><version>1.8.0</version><description></description><post-install type="none"/><requireAuthorization/><installFrom mod="true">/Users/paul/task.git/package-config/osx/binary/task</installFrom><installTo mod="true" relocatable="true">/usr/local/bin</installTo><flags><followSymbolicLinks/></flags><packageStore type="internal"></packageStore><mod>parent</mod><mod>locationType</mod><mod>relocatable</mod><mod>version</mod><mod>installTo.path</mod><mod>installTo</mod></config><contents><file-list>01task-contents.xml</file-list><filter>/CVS$</filter><filter>/\.svn$</filter><filter>/\.cvsignore$</filter><filter>/\.cvspass$</filter><filter>/\.DS_Store$</filter></contents></pkgref>
|
||||
<pkgref spec="1.12" uuid="C71026FD-E252-42CD-89C3-2F6F087AAF17"><config><identifier>com.beckingham.task182.task.pkg</identifier><version>1.8.2</version><description></description><post-install type="none"/><requireAuthorization/><installFrom mod="true">/Users/paul/task.git/package-config/osx/binary/task</installFrom><installTo mod="true" relocatable="true">/usr/local/bin</installTo><flags><followSymbolicLinks/></flags><packageStore type="internal"></packageStore><mod>installTo</mod><mod>locationType</mod><mod>relocatable</mod><mod>identifier</mod><mod>parent</mod><mod>version</mod><mod>installTo.path</mod></config><contents><file-list>01task-contents.xml</file-list><filter>/CVS$</filter><filter>/\.svn$</filter><filter>/\.cvsignore$</filter><filter>/\.cvspass$</filter><filter>/\.DS_Store$</filter></contents></pkgref>
|
||||
@@ -1 +1 @@
|
||||
<pkmkdoc spec="1.12"><properties><title>Task 1.8.0</title><build>/Users/paul/Desktop/task-1.8.0.pkg</build><organization>com.beckingham</organization><userSees ui="easy"/><min-target os="3"/><domain anywhere="true" system="true"/></properties><distribution><versions min-spec="1.000000"/><scripts></scripts></distribution><contents><choice title="task" id="choice0" starts_selected="true" starts_enabled="true" starts_hidden="false"><pkgref id="com.beckingham.task180.task.pkg"/><choice-reqs><requirement id="tosv" operator="ge" value="'10.5.0'" selected="no" enabled="no" hidden="unchanged" startSelected="unchanged" startEnabled="unchanged" startHidden="unchanged"/></choice-reqs></choice></contents><resources bg-scale="proportional" bg-align="center"><locale lang="en"><resource mod="true" type="license">/Users/paul/task.git/package-config/osx/binary/COPYING.txt</resource><resource mod="true" type="readme">/Users/paul/task.git/package-config/osx/binary/README.txt</resource></locale></resources><flags/><item type="file">01task.xml</item><mod>properties.title</mod><mod>properties.anywhereDomain</mod><mod>properties.systemDomain</mod></pkmkdoc>
|
||||
<pkmkdoc spec="1.12"><properties><title>Task 1.8.2</title><build>/Users/paul/Desktop/task-1.8.2.pkg</build><organization>com.beckingham</organization><userSees ui="both"/><min-target os="3"/><domain anywhere="true" system="true"/></properties><distribution><versions min-spec="1.000000"/><scripts></scripts></distribution><contents><choice title="task" id="choice0" starts_selected="true" starts_enabled="true" starts_hidden="false"><pkgref id="com.beckingham.task182.task.pkg"/><choice-reqs><requirement id="tosv" operator="ge" value="'10.6.0'" selected="no" enabled="no" hidden="unchanged" startSelected="unchanged" startEnabled="unchanged" startHidden="unchanged"/></choice-reqs></choice></contents><resources bg-scale="proportional" bg-align="center"><locale lang="en"><resource mod="true" type="license">/Users/paul/task.git/package-config/osx/binary/COPYING.txt</resource><resource mod="true" type="readme">/Users/paul/task.git/package-config/osx/binary/README.txt</resource></locale></resources><flags/><item type="file">01task.xml</item><mod>properties.title</mod><mod>properties.customizeOption</mod><mod>properties.anywhereDomain</mod><mod>properties.systemDomain</mod></pkmkdoc>
|
||||
101
src/Context.cpp
101
src/Context.cpp
@@ -30,6 +30,7 @@
|
||||
#include <pwd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "Context.h"
|
||||
#include "Timer.h"
|
||||
#include "text.h"
|
||||
@@ -49,6 +50,7 @@ Context::Context ()
|
||||
, tdb ()
|
||||
, stringtable ()
|
||||
, program ("")
|
||||
, overrides ("")
|
||||
, cmd ()
|
||||
, inShadow (false)
|
||||
{
|
||||
@@ -126,23 +128,26 @@ void Context::initialize ()
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int Context::run ()
|
||||
{
|
||||
int rc;
|
||||
Timer t ("Context::run");
|
||||
|
||||
std::string output;
|
||||
try
|
||||
{
|
||||
parse (); // Parse command line.
|
||||
output = dispatch (); // Dispatch to command handlers.
|
||||
parse (); // Parse command line.
|
||||
rc = dispatch (output); // Dispatch to command handlers.
|
||||
}
|
||||
|
||||
catch (const std::string& error)
|
||||
{
|
||||
footnote (error);
|
||||
rc = 2;
|
||||
}
|
||||
|
||||
catch (...)
|
||||
{
|
||||
footnote (stringtable.get (100, "Unknown error."));
|
||||
rc = 3;
|
||||
}
|
||||
|
||||
// Dump all debug messages.
|
||||
@@ -170,63 +175,63 @@ int Context::run ()
|
||||
else
|
||||
std::cout << *f << std::endl;
|
||||
|
||||
return 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string Context::dispatch ()
|
||||
int Context::dispatch (std::string &out)
|
||||
{
|
||||
int rc = 0;
|
||||
Timer t ("Context::dispatch");
|
||||
|
||||
// TODO Just look at this thing. It cries out for a dispatch table.
|
||||
std::string out;
|
||||
if (cmd.command == "projects") { out = handleProjects (); }
|
||||
else if (cmd.command == "tags") { out = handleTags (); }
|
||||
else if (cmd.command == "colors") { out = handleColor (); }
|
||||
else if (cmd.command == "version") { out = handleVersion (); }
|
||||
else if (cmd.command == "help") { out = longUsage (); }
|
||||
else if (cmd.command == "stats") { out = handleReportStats (); }
|
||||
else if (cmd.command == "info") { out = handleInfo (); }
|
||||
else if (cmd.command == "history") { out = handleReportHistory (); }
|
||||
else if (cmd.command == "ghistory") { out = handleReportGHistory (); }
|
||||
else if (cmd.command == "summary") { out = handleReportSummary (); }
|
||||
else if (cmd.command == "calendar") { out = handleReportCalendar (); }
|
||||
else if (cmd.command == "timesheet") { out = handleReportTimesheet (); }
|
||||
else if (cmd.command == "add") { out = handleAdd (); }
|
||||
else if (cmd.command == "append") { out = handleAppend (); }
|
||||
else if (cmd.command == "annotate") { out = handleAnnotate (); }
|
||||
else if (cmd.command == "done") { out = handleDone (); }
|
||||
else if (cmd.command == "delete") { out = handleDelete (); }
|
||||
else if (cmd.command == "start") { out = handleStart (); }
|
||||
else if (cmd.command == "stop") { out = handleStop (); }
|
||||
else if (cmd.command == "export") { out = handleExport (); }
|
||||
else if (cmd.command == "import") { out = handleImport (); }
|
||||
else if (cmd.command == "duplicate") { out = handleDuplicate (); }
|
||||
else if (cmd.command == "edit") { out = handleEdit (); }
|
||||
if (cmd.command == "projects") { rc = handleProjects (out); }
|
||||
else if (cmd.command == "tags") { rc = handleTags (out); }
|
||||
else if (cmd.command == "colors") { rc = handleColor (out); }
|
||||
else if (cmd.command == "version") { rc = handleVersion (out); }
|
||||
else if (cmd.command == "help") { rc = longUsage (out); }
|
||||
else if (cmd.command == "stats") { rc = handleReportStats (out); }
|
||||
else if (cmd.command == "info") { rc = handleInfo (out); }
|
||||
else if (cmd.command == "history") { rc = handleReportHistory (out); }
|
||||
else if (cmd.command == "ghistory") { rc = handleReportGHistory (out); }
|
||||
else if (cmd.command == "summary") { rc = handleReportSummary (out); }
|
||||
else if (cmd.command == "calendar") { rc = handleReportCalendar (out); }
|
||||
else if (cmd.command == "timesheet") { rc = handleReportTimesheet (out); }
|
||||
else if (cmd.command == "add") { rc = handleAdd (out); }
|
||||
else if (cmd.command == "append") { rc = handleAppend (out); }
|
||||
else if (cmd.command == "annotate") { rc = handleAnnotate (out); }
|
||||
else if (cmd.command == "done") { rc = handleDone (out); }
|
||||
else if (cmd.command == "delete") { rc = handleDelete (out); }
|
||||
else if (cmd.command == "start") { rc = handleStart (out); }
|
||||
else if (cmd.command == "stop") { rc = handleStop (out); }
|
||||
else if (cmd.command == "export") { rc = handleExport (out); }
|
||||
else if (cmd.command == "import") { rc = handleImport (out); }
|
||||
else if (cmd.command == "duplicate") { rc = handleDuplicate (out); }
|
||||
else if (cmd.command == "edit") { rc = handleEdit (out); }
|
||||
#ifdef FEATURE_SHELL
|
||||
else if (cmd.command == "shell") { handleShell (); }
|
||||
else if (cmd.command == "shell") { handleShell ( ); }
|
||||
#endif
|
||||
else if (cmd.command == "undo") { handleUndo (); }
|
||||
else if (cmd.command == "_projects") { out = handleCompletionProjects (); }
|
||||
else if (cmd.command == "_tags") { out = handleCompletionTags (); }
|
||||
else if (cmd.command == "_commands") { out = handleCompletionCommands (); }
|
||||
else if (cmd.command == "_ids") { out = handleCompletionIDs (); }
|
||||
else if (cmd.command == "_config") { out = handleCompletionConfig (); }
|
||||
else if (cmd.command == "undo") { handleUndo ( ); }
|
||||
else if (cmd.command == "_projects") { rc = handleCompletionProjects (out); }
|
||||
else if (cmd.command == "_tags") { rc = handleCompletionTags (out); }
|
||||
else if (cmd.command == "_commands") { rc = handleCompletionCommands (out); }
|
||||
else if (cmd.command == "_ids") { rc = handleCompletionIDs (out); }
|
||||
else if (cmd.command == "_config") { rc = handleCompletionConfig (out); }
|
||||
else if (cmd.command == "" &&
|
||||
sequence.size ()) { out = handleModify (); }
|
||||
sequence.size ()) { rc = handleModify (out); }
|
||||
|
||||
// Command that display IDs and therefore need TDB::gc first.
|
||||
else if (cmd.command == "next") { if (!inShadow) tdb.gc (); out = handleReportNext (); }
|
||||
else if (cmd.validCustom (cmd.command)) { if (!inShadow) tdb.gc (); out = handleCustomReport (cmd.command); }
|
||||
else if (cmd.command == "next") { if (!inShadow) tdb.gc (); rc = handleReportNext (out); }
|
||||
else if (cmd.validCustom (cmd.command)) { if (!inShadow) tdb.gc (); rc = handleCustomReport (cmd.command, out); }
|
||||
|
||||
// If the command is not recognized, display usage.
|
||||
else { out = shortUsage (); }
|
||||
else { rc = shortUsage (out); }
|
||||
|
||||
// Only update the shadow file if such an update was not suppressed (shadow),
|
||||
if (cmd.isWriteCommand () && !inShadow)
|
||||
shadow ();
|
||||
|
||||
return out;
|
||||
return rc;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -252,8 +257,6 @@ void Context::shadow ()
|
||||
|
||||
std::string oldCurses = config.get ("curses");
|
||||
std::string oldColor = config.get ("color");
|
||||
config.set ("curses", "off");
|
||||
config.set ("color", "off");
|
||||
|
||||
clear ();
|
||||
|
||||
@@ -264,8 +267,12 @@ void Context::shadow ()
|
||||
split (args, command, ' ');
|
||||
|
||||
initialize ();
|
||||
config.set ("curses", "off");
|
||||
config.set ("color", "off");
|
||||
|
||||
parse ();
|
||||
std::string result = dispatch ();
|
||||
std::string result;
|
||||
(void)dispatch (result);
|
||||
std::ofstream out (shadowFile.c_str ());
|
||||
if (out.good ())
|
||||
{
|
||||
@@ -433,6 +440,7 @@ void Context::loadCorrectConfigFile ()
|
||||
n.getUntilEOS (value))
|
||||
{
|
||||
config.set (name, value);
|
||||
overrides += " " + *arg;
|
||||
footnote (std::string ("Configuration override ") + // TODO i18n
|
||||
arg->substr (3, std::string::npos));
|
||||
}
|
||||
@@ -649,12 +657,13 @@ void Context::parse (
|
||||
// then invoke the default command.
|
||||
if (parseCmd.command == "" && parseArgs.size () == 0)
|
||||
{
|
||||
std::string defaultCommand = config.get ("default.command");
|
||||
// Apply overrides, if any.
|
||||
std::string defaultCommand = config.get ("default.command") + overrides;
|
||||
if (defaultCommand != "")
|
||||
{
|
||||
// Stuff the command line.
|
||||
parseArgs.clear ();
|
||||
split (parseArgs, defaultCommand, ' ');
|
||||
args.clear ();
|
||||
split (args, defaultCommand, ' ');
|
||||
header ("[task " + defaultCommand + "]");
|
||||
|
||||
// Reinitialize the context and recurse.
|
||||
|
||||
@@ -50,7 +50,7 @@ public:
|
||||
void initialize (); // for reinitializing
|
||||
int run (); // task classic
|
||||
int interactive (); // task interactive (not implemented)
|
||||
std::string dispatch (); // command handler dispatch
|
||||
int dispatch (std::string&); // command handler dispatch
|
||||
void shadow (); // shadow file update
|
||||
|
||||
int getWidth (); // determine terminal width
|
||||
@@ -83,6 +83,7 @@ public:
|
||||
StringTable stringtable;
|
||||
std::string program;
|
||||
std::vector <std::string> args;
|
||||
std::string overrides;
|
||||
Cmd cmd;
|
||||
std::map <std::string, std::string> aliases;
|
||||
std::vector <std::string> tagAdditions;
|
||||
|
||||
29
src/Date.cpp
29
src/Date.cpp
@@ -29,6 +29,7 @@
|
||||
#include <time.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include "Date.h"
|
||||
#include "text.h"
|
||||
#include "util.h"
|
||||
@@ -82,14 +83,14 @@ Date::Date (const std::string& mdy, const std::string& format /* = "m/d/Y" */)
|
||||
// Single or double digit.
|
||||
case 'm':
|
||||
if (i >= mdy.length () ||
|
||||
! ::isdigit (mdy[i]))
|
||||
! isdigit (mdy[i]))
|
||||
{
|
||||
throw std::string ("\"") + mdy + "\" is not a valid date.";
|
||||
}
|
||||
|
||||
if (i + 1 < mdy.length () &&
|
||||
(mdy[i + 0] == '0' || mdy[i + 0] == '1') &&
|
||||
::isdigit (mdy[i + 1]))
|
||||
isdigit (mdy[i + 1]))
|
||||
{
|
||||
month = ::atoi (mdy.substr (i, 2).c_str ());
|
||||
i += 2;
|
||||
@@ -103,14 +104,14 @@ Date::Date (const std::string& mdy, const std::string& format /* = "m/d/Y" */)
|
||||
|
||||
case 'd':
|
||||
if (i >= mdy.length () ||
|
||||
! ::isdigit (mdy[i]))
|
||||
! isdigit (mdy[i]))
|
||||
{
|
||||
throw std::string ("\"") + mdy + "\" is not a valid date.";
|
||||
}
|
||||
|
||||
if (i + 1 < mdy.length () &&
|
||||
(mdy[i + 0] == '0' || mdy[i + 0] == '1' || mdy[i + 0] == '2' || mdy[i + 0] == '3') &&
|
||||
::isdigit (mdy[i + 1]))
|
||||
isdigit (mdy[i + 1]))
|
||||
{
|
||||
day = ::atoi (mdy.substr (i, 2).c_str ());
|
||||
i += 2;
|
||||
@@ -125,8 +126,8 @@ Date::Date (const std::string& mdy, const std::string& format /* = "m/d/Y" */)
|
||||
// Double digit.
|
||||
case 'y':
|
||||
if (i + 1 >= mdy.length () ||
|
||||
! ::isdigit (mdy[i + 0]) ||
|
||||
! ::isdigit (mdy[i + 1]))
|
||||
! isdigit (mdy[i + 0]) ||
|
||||
! isdigit (mdy[i + 1]))
|
||||
{
|
||||
throw std::string ("\"") + mdy + "\" is not a valid date.";
|
||||
}
|
||||
@@ -137,8 +138,8 @@ Date::Date (const std::string& mdy, const std::string& format /* = "m/d/Y" */)
|
||||
|
||||
case 'M':
|
||||
if (i + 1 >= mdy.length () ||
|
||||
! ::isdigit (mdy[i + 0]) ||
|
||||
! ::isdigit (mdy[i + 1]))
|
||||
! isdigit (mdy[i + 0]) ||
|
||||
! isdigit (mdy[i + 1]))
|
||||
{
|
||||
throw std::string ("\"") + mdy + "\" is not a valid date.";
|
||||
}
|
||||
@@ -149,8 +150,8 @@ Date::Date (const std::string& mdy, const std::string& format /* = "m/d/Y" */)
|
||||
|
||||
case 'D':
|
||||
if (i + 1 >= mdy.length () ||
|
||||
! ::isdigit (mdy[i + 0]) ||
|
||||
! ::isdigit (mdy[i + 1]))
|
||||
! isdigit (mdy[i + 0]) ||
|
||||
! isdigit (mdy[i + 1]))
|
||||
{
|
||||
throw std::string ("\"") + mdy + "\" is not a valid date.";
|
||||
}
|
||||
@@ -162,10 +163,10 @@ Date::Date (const std::string& mdy, const std::string& format /* = "m/d/Y" */)
|
||||
// Quadruple digit.
|
||||
case 'Y':
|
||||
if (i + 3 >= mdy.length () ||
|
||||
! ::isdigit (mdy[i + 0]) ||
|
||||
! ::isdigit (mdy[i + 1]) ||
|
||||
! ::isdigit (mdy[i + 2]) ||
|
||||
! ::isdigit (mdy[i + 3]))
|
||||
! isdigit (mdy[i + 0]) ||
|
||||
! isdigit (mdy[i + 1]) ||
|
||||
! isdigit (mdy[i + 2]) ||
|
||||
! isdigit (mdy[i + 3]))
|
||||
{
|
||||
throw std::string ("\"") + mdy + "\" is not a valid date.";
|
||||
}
|
||||
|
||||
@@ -243,7 +243,7 @@ bool Nibbler::getInt (int& result)
|
||||
++i;
|
||||
}
|
||||
|
||||
while (i < mInput.length () && ::isdigit (mInput[i]))
|
||||
while (i < mInput.length () && isdigit (mInput[i]))
|
||||
++i;
|
||||
|
||||
if (i > mCursor)
|
||||
@@ -260,7 +260,7 @@ bool Nibbler::getInt (int& result)
|
||||
bool Nibbler::getUnsignedInt (int& result)
|
||||
{
|
||||
std::string::size_type i = mCursor;
|
||||
while (i < mInput.length () && ::isdigit (mInput[i]))
|
||||
while (i < mInput.length () && isdigit (mInput[i]))
|
||||
++i;
|
||||
|
||||
if (i > mCursor)
|
||||
|
||||
@@ -153,7 +153,7 @@ bool Sequence::validId (const std::string& input) const
|
||||
return false;
|
||||
|
||||
for (size_t i = 0; i < input.length (); ++i)
|
||||
if (!::isdigit (input[i]))
|
||||
if (!isdigit (input[i]))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
||||
@@ -876,7 +876,7 @@ void Table::sort (std::vector <int>& order)
|
||||
if (gap > 1)
|
||||
{
|
||||
gap = (int) ((float)gap / 1.3);
|
||||
if (gap == 10 or gap == 9)
|
||||
if (gap == 10 || gap == 9)
|
||||
gap = 11;
|
||||
}
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ Timer::~Timer ()
|
||||
<< mDescription
|
||||
<< " "
|
||||
<< std::setprecision (6)
|
||||
<< std::fixed
|
||||
// << std::fixed
|
||||
<< ((end.tv_sec - mStart.tv_sec) + ((end.tv_usec - mStart.tv_usec )
|
||||
/ 1000000.0))
|
||||
<< " sec";
|
||||
|
||||
130
src/command.cpp
130
src/command.cpp
@@ -49,7 +49,7 @@
|
||||
extern Context context;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string handleAdd ()
|
||||
int handleAdd (std::string &outs)
|
||||
{
|
||||
std::stringstream out;
|
||||
|
||||
@@ -110,12 +110,14 @@ std::string handleAdd ()
|
||||
context.tdb.commit ();
|
||||
context.tdb.unlock ();
|
||||
|
||||
return out.str ();
|
||||
outs = out.str ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string handleProjects ()
|
||||
int handleProjects (std::string &outs)
|
||||
{
|
||||
int rc = 0;
|
||||
std::stringstream out;
|
||||
|
||||
context.filter.push_back (Att ("status", "pending"));
|
||||
@@ -195,15 +197,18 @@ std::string handleProjects ()
|
||||
<< " (" << quantity << (quantity == 1 ? " task" : " tasks") << ")"
|
||||
<< std::endl;
|
||||
}
|
||||
else
|
||||
else {
|
||||
out << "No projects."
|
||||
<< std::endl;
|
||||
rc = 1;
|
||||
}
|
||||
|
||||
return out.str ();
|
||||
outs = out.str ();
|
||||
return rc;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string handleCompletionProjects ()
|
||||
int handleCompletionProjects (std::string &outs)
|
||||
{
|
||||
std::vector <Task> tasks;
|
||||
context.tdb.lock (context.config.get ("locking", true));
|
||||
@@ -228,12 +233,14 @@ std::string handleCompletionProjects ()
|
||||
if (project->first.length ())
|
||||
out << project->first << std::endl;
|
||||
|
||||
return out.str ();
|
||||
outs = out.str ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string handleTags ()
|
||||
int handleTags (std::string &outs)
|
||||
{
|
||||
int rc = 0;
|
||||
std::stringstream out;
|
||||
|
||||
context.filter.push_back (Att ("status", "pending"));
|
||||
@@ -290,15 +297,19 @@ std::string handleTags ()
|
||||
<< " (" << quantity << (quantity == 1 ? " task" : " tasks") << ")"
|
||||
<< std::endl;
|
||||
}
|
||||
else
|
||||
else {
|
||||
out << "No tags."
|
||||
<< std::endl;
|
||||
rc = 1;
|
||||
}
|
||||
|
||||
return out.str ();
|
||||
outs = out.str ();
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string handleCompletionTags ()
|
||||
int handleCompletionTags (std::string &outs)
|
||||
{
|
||||
std::vector <Task> tasks;
|
||||
context.tdb.lock (context.config.get ("locking", true));
|
||||
@@ -328,11 +339,12 @@ std::string handleCompletionTags ()
|
||||
foreach (tag, unique)
|
||||
out << tag->first << std::endl;
|
||||
|
||||
return out.str ();
|
||||
outs = out.str ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string handleCompletionCommands ()
|
||||
int handleCompletionCommands (std::string &outs)
|
||||
{
|
||||
std::vector <std::string> commands;
|
||||
context.cmd.allCommands (commands);
|
||||
@@ -342,11 +354,12 @@ std::string handleCompletionCommands ()
|
||||
foreach (command, commands)
|
||||
out << *command << std::endl;
|
||||
|
||||
return out.str ();
|
||||
outs = out.str ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string handleCompletionConfig ()
|
||||
int handleCompletionConfig (std::string &outs)
|
||||
{
|
||||
std::vector <std::string> configs;
|
||||
context.config.all (configs);
|
||||
@@ -356,11 +369,12 @@ std::string handleCompletionConfig ()
|
||||
foreach (config, configs)
|
||||
out << *config << std::endl;
|
||||
|
||||
return out.str ();
|
||||
outs = out.str ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string handleCompletionIDs ()
|
||||
int handleCompletionIDs (std::string &outs)
|
||||
{
|
||||
std::vector <Task> tasks;
|
||||
context.tdb.lock (context.config.get ("locking", true));
|
||||
@@ -381,7 +395,8 @@ std::string handleCompletionIDs ()
|
||||
foreach (id, ids)
|
||||
out << *id << std::endl;
|
||||
|
||||
return out.str ();
|
||||
outs = out.str ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -395,8 +410,9 @@ void handleUndo ()
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string handleVersion ()
|
||||
int handleVersion (std::string &outs)
|
||||
{
|
||||
int rc = 0;
|
||||
std::stringstream out;
|
||||
|
||||
// Create a table for the disclaimer.
|
||||
@@ -483,8 +499,8 @@ std::string handleVersion ()
|
||||
" blanklines bulk color color.active color.due color.overdue color.pri.H "
|
||||
"color.pri.L color.pri.M color.pri.none color.recurring color.tagged "
|
||||
"color.footnote color.header color.debug confirmation curses data.location "
|
||||
"dateformat debug default.command default.priority defaultwidth due locale "
|
||||
"displayweeknumber echo.command locking monthsperline nag next project "
|
||||
"dateformat debug default.command default.priority default.project defaultwidth "
|
||||
"due locale displayweeknumber echo.command locking monthsperline nag next project "
|
||||
"shadow.command shadow.file shadow.notify weekstart editor import.synonym.id "
|
||||
"import.synonym.uuid longversion complete.all.projects complete.all.tags "
|
||||
#ifdef FEATURE_SHELL
|
||||
@@ -524,7 +540,7 @@ std::string handleVersion ()
|
||||
if (unrecognized.size ())
|
||||
{
|
||||
out << "Your .taskrc file contains these unrecognized variables:"
|
||||
<< std::endl;
|
||||
<< std::endl;
|
||||
|
||||
foreach (i, unrecognized)
|
||||
out << " " << *i << std::endl;
|
||||
@@ -535,9 +551,11 @@ std::string handleVersion ()
|
||||
// Verify installation. This is mentioned in the documentation as the way to
|
||||
// ensure everything is properly installed.
|
||||
|
||||
if (all.size () == 0)
|
||||
if (all.size () == 0) {
|
||||
out << "Configuration error: .taskrc contains no entries"
|
||||
<< std::endl;
|
||||
rc = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (context.config.get ("data.location") == "")
|
||||
@@ -551,12 +569,14 @@ std::string handleVersion ()
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
return out.str ();
|
||||
outs = out.str ();
|
||||
return rc;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string handleDelete ()
|
||||
int handleDelete (std::string &outs)
|
||||
{
|
||||
int rc = 0;
|
||||
std::stringstream out;
|
||||
|
||||
context.disallowModification ();
|
||||
@@ -645,19 +665,23 @@ std::string handleDelete ()
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
else {
|
||||
out << "Task not deleted." << std::endl;
|
||||
rc = 1;
|
||||
}
|
||||
}
|
||||
|
||||
context.tdb.commit ();
|
||||
context.tdb.unlock ();
|
||||
|
||||
return out.str ();
|
||||
outs = out.str ();
|
||||
return rc;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string handleStart ()
|
||||
int handleStart (std::string &outs)
|
||||
{
|
||||
int rc = 0;
|
||||
std::stringstream out;
|
||||
|
||||
context.disallowModification ();
|
||||
@@ -699,18 +723,21 @@ std::string handleStart ()
|
||||
<< task->get ("description")
|
||||
<< "' already started."
|
||||
<< std::endl;
|
||||
rc = 1;
|
||||
}
|
||||
}
|
||||
|
||||
context.tdb.commit ();
|
||||
context.tdb.unlock ();
|
||||
|
||||
return out.str ();
|
||||
outs = out.str ();
|
||||
return rc;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string handleStop ()
|
||||
int handleStop (std::string &outs)
|
||||
{
|
||||
int rc = 0;
|
||||
std::stringstream out;
|
||||
|
||||
context.disallowModification ();
|
||||
@@ -746,18 +773,21 @@ std::string handleStop ()
|
||||
<< task->get ("description")
|
||||
<< "' not started."
|
||||
<< std::endl;
|
||||
rc = 1;
|
||||
}
|
||||
}
|
||||
|
||||
context.tdb.commit ();
|
||||
context.tdb.unlock ();
|
||||
|
||||
return out.str ();
|
||||
outs = out.str ();
|
||||
return rc;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string handleDone ()
|
||||
int handleDone (std::string &outs)
|
||||
{
|
||||
int rc = 0;
|
||||
int count = 0;
|
||||
std::stringstream out;
|
||||
|
||||
@@ -826,6 +856,7 @@ std::string handleDone ()
|
||||
<< task->get ("description")
|
||||
<< "' is not pending"
|
||||
<< std::endl;
|
||||
rc = 1;
|
||||
}
|
||||
|
||||
context.tdb.commit ();
|
||||
@@ -839,11 +870,12 @@ std::string handleDone ()
|
||||
<< " as done"
|
||||
<< std::endl;
|
||||
|
||||
return out.str ();
|
||||
outs = out.str ();
|
||||
return rc;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string handleExport ()
|
||||
int handleExport (std::string &outs)
|
||||
{
|
||||
std::stringstream out;
|
||||
|
||||
@@ -882,11 +914,12 @@ std::string handleExport ()
|
||||
}
|
||||
}
|
||||
|
||||
return out.str ();
|
||||
outs = out.str ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string handleModify ()
|
||||
int handleModify (std::string &outs)
|
||||
{
|
||||
int count = 0;
|
||||
std::stringstream out;
|
||||
@@ -959,11 +992,12 @@ std::string handleModify ()
|
||||
if (context.config.get ("echo.command", true))
|
||||
out << "Modified " << count << " task" << (count == 1 ? "" : "s") << std::endl;
|
||||
|
||||
return out.str ();
|
||||
outs = out.str ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string handleAppend ()
|
||||
int handleAppend (std::string &outs)
|
||||
{
|
||||
int count = 0;
|
||||
std::stringstream out;
|
||||
@@ -1026,11 +1060,12 @@ std::string handleAppend ()
|
||||
if (context.config.get ("echo.command", true))
|
||||
out << "Appended " << count << " task" << (count == 1 ? "" : "s") << std::endl;
|
||||
|
||||
return out.str ();
|
||||
outs = out.str ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string handleDuplicate ()
|
||||
int handleDuplicate (std::string &outs)
|
||||
{
|
||||
std::stringstream out;
|
||||
int count = 0;
|
||||
@@ -1095,7 +1130,8 @@ std::string handleDuplicate ()
|
||||
if (context.config.get ("echo.command", true))
|
||||
out << "Duplicated " << count << " task" << (count == 1 ? "" : "s") << std::endl;
|
||||
|
||||
return out.str ();
|
||||
outs = out.str ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -1174,8 +1210,9 @@ void handleShell ()
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string handleColor ()
|
||||
int handleColor (std::string &outs)
|
||||
{
|
||||
int rc = 0;
|
||||
std::stringstream out;
|
||||
if (context.config.get ("color", true) || context.config.get (std::string ("_forcecolor"), false))
|
||||
{
|
||||
@@ -1257,13 +1294,15 @@ std::string handleColor ()
|
||||
out << "Color is currently turned off in your .taskrc file. "
|
||||
"To enable color, create the entry 'color=on'."
|
||||
<< std::endl;
|
||||
rc = 1;
|
||||
}
|
||||
|
||||
return out.str ();
|
||||
outs = out.str ();
|
||||
return rc;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string handleAnnotate ()
|
||||
int handleAnnotate (std::string &outs)
|
||||
{
|
||||
if (!context.task.has ("description"))
|
||||
throw std::string ("Cannot apply a blank annotation.");
|
||||
@@ -1307,7 +1346,8 @@ std::string handleAnnotate ()
|
||||
context.tdb.commit ();
|
||||
context.tdb.unlock ();
|
||||
|
||||
return out.str ();
|
||||
outs = out.str ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -52,7 +52,7 @@ static std::vector <std::string> customReports;
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// This report will eventually become the one report that many others morph into
|
||||
// via the .taskrc file.
|
||||
std::string handleCustomReport (const std::string& report)
|
||||
int handleCustomReport (const std::string& report, std::string &outs)
|
||||
{
|
||||
// Load report configuration.
|
||||
std::string columnList = context.config.get ("report." + report + ".columns");
|
||||
@@ -94,21 +94,24 @@ std::string handleCustomReport (const std::string& report)
|
||||
labelList,
|
||||
sortList,
|
||||
filterList,
|
||||
tasks);
|
||||
tasks,
|
||||
outs);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// This report will eventually become the one report that many others morph into
|
||||
// via the .taskrc file.
|
||||
|
||||
std::string runCustomReport (
|
||||
int runCustomReport (
|
||||
const std::string& report,
|
||||
const std::string& columnList,
|
||||
const std::string& labelList,
|
||||
const std::string& sortList,
|
||||
const std::string& filterList,
|
||||
std::vector <Task>& tasks)
|
||||
std::vector <Task>& tasks,
|
||||
std::string &outs)
|
||||
{
|
||||
int rc = 0;
|
||||
// Load report configuration.
|
||||
std::vector <std::string> columns;
|
||||
split (columns, columnList, ',');
|
||||
@@ -547,11 +550,14 @@ std::string runCustomReport (
|
||||
<< table.rowCount ()
|
||||
<< (table.rowCount () == 1 ? " task" : " tasks")
|
||||
<< std::endl;
|
||||
else
|
||||
else {
|
||||
out << "No matches."
|
||||
<< std::endl;
|
||||
rc = 1;
|
||||
}
|
||||
|
||||
return out.str ();
|
||||
outs = out.str ();
|
||||
return rc;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -599,7 +599,7 @@ ARE_THESE_REALLY_HARMFUL:
|
||||
// Introducing the Silver Bullet. This feature is the catch-all fixative for
|
||||
// various other ills. This is like opening up the hood and going in with a
|
||||
// wrench. To be used sparingly.
|
||||
std::string handleEdit ()
|
||||
int handleEdit (std::string &outs)
|
||||
{
|
||||
std::stringstream out;
|
||||
|
||||
@@ -643,7 +643,8 @@ std::string handleEdit ()
|
||||
context.tdb.commit ();
|
||||
context.tdb.unlock ();
|
||||
|
||||
return out.str ();
|
||||
outs = out.str ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -106,16 +106,16 @@ static fileType determineFileType (const std::vector <std::string>& lines)
|
||||
{
|
||||
if ( lines[i][0] == 'x' &&
|
||||
lines[i][1] == ' ' &&
|
||||
::isdigit (lines[i][2]) &&
|
||||
::isdigit (lines[i][3]) &&
|
||||
::isdigit (lines[i][4]) &&
|
||||
::isdigit (lines[i][5]) &&
|
||||
isdigit (lines[i][2]) &&
|
||||
isdigit (lines[i][3]) &&
|
||||
isdigit (lines[i][4]) &&
|
||||
isdigit (lines[i][5]) &&
|
||||
lines[i][6] == '-' &&
|
||||
::isdigit (lines[i][7]) &&
|
||||
::isdigit (lines[i][8]) &&
|
||||
isdigit (lines[i][7]) &&
|
||||
isdigit (lines[i][8]) &&
|
||||
lines[i][9] == '-' &&
|
||||
::isdigit (lines[i][10]) &&
|
||||
::isdigit (lines[i][11]))
|
||||
isdigit (lines[i][10]) &&
|
||||
isdigit (lines[i][11]))
|
||||
return todo_sh_2_0;
|
||||
}
|
||||
|
||||
@@ -126,13 +126,13 @@ static fileType determineFileType (const std::vector <std::string>& lines)
|
||||
// +project
|
||||
if (words[w].length () > 1 &&
|
||||
words[w][0] == '+' &&
|
||||
::isalnum (words[w][1]))
|
||||
isalnum (words[w][1]))
|
||||
return todo_sh_2_0;
|
||||
|
||||
// @context
|
||||
if (words[w].length () > 1 &&
|
||||
words[w][0] == '@' &&
|
||||
::isalnum (words[w][1]))
|
||||
isalnum (words[w][1]))
|
||||
return todo_sh_2_0;
|
||||
}
|
||||
}
|
||||
@@ -666,6 +666,7 @@ static std::string importTask_1_6_0 (const std::vector <std::string>& lines)
|
||||
static std::string importTaskCmdLine (const std::vector <std::string>& lines)
|
||||
{
|
||||
std::vector <std::string> failed;
|
||||
std::string unused;
|
||||
|
||||
std::vector <std::string>::const_iterator it;
|
||||
for (it = lines.begin (); it != lines.end (); ++it)
|
||||
@@ -680,7 +681,7 @@ static std::string importTaskCmdLine (const std::vector <std::string>& lines)
|
||||
context.task.clear ();
|
||||
context.cmd.command = "";
|
||||
context.parse ();
|
||||
handleAdd ();
|
||||
(void)handleAdd (unused);
|
||||
context.clearMessages ();
|
||||
}
|
||||
|
||||
@@ -789,6 +790,8 @@ static std::string importTodoSh_2_0 (const std::vector <std::string>& lines)
|
||||
context.parse ();
|
||||
decorateTask (context.task);
|
||||
|
||||
context.task.set ("uuid", uuid ());
|
||||
|
||||
if (isPending)
|
||||
{
|
||||
context.task.setStatus (Task::pending);
|
||||
@@ -1144,7 +1147,7 @@ static std::string importCSV (const std::vector <std::string>& lines)
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string handleImport ()
|
||||
int handleImport (std::string &outs)
|
||||
{
|
||||
std::stringstream out;
|
||||
|
||||
@@ -1212,7 +1215,8 @@ std::string handleImport ()
|
||||
else
|
||||
throw std::string ("You must specify a file to import.");
|
||||
|
||||
return out.str ();
|
||||
outs = out.str ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
71
src/main.h
71
src/main.h
@@ -55,25 +55,25 @@ int getDueState (const std::string&);
|
||||
bool nag (Task&);
|
||||
|
||||
// command.cpp
|
||||
std::string handleAdd ();
|
||||
std::string handleAppend ();
|
||||
std::string handleExport ();
|
||||
std::string handleDone ();
|
||||
std::string handleModify ();
|
||||
std::string handleProjects ();
|
||||
std::string handleCompletionProjects ();
|
||||
std::string handleTags ();
|
||||
std::string handleCompletionTags ();
|
||||
std::string handleCompletionCommands ();
|
||||
std::string handleCompletionIDs ();
|
||||
std::string handleCompletionConfig ();
|
||||
std::string handleVersion ();
|
||||
std::string handleDelete ();
|
||||
std::string handleStart ();
|
||||
std::string handleStop ();
|
||||
std::string handleColor ();
|
||||
std::string handleAnnotate ();
|
||||
std::string handleDuplicate ();
|
||||
int handleAdd (std::string &);
|
||||
int handleAppend (std::string &);
|
||||
int handleExport (std::string &);
|
||||
int handleDone (std::string &);
|
||||
int handleModify (std::string &);
|
||||
int handleProjects (std::string &);
|
||||
int handleCompletionProjects (std::string &);
|
||||
int handleTags (std::string &);
|
||||
int handleCompletionTags (std::string &);
|
||||
int handleCompletionCommands (std::string &);
|
||||
int handleCompletionIDs (std::string &);
|
||||
int handleCompletionConfig (std::string &);
|
||||
int handleVersion (std::string &);
|
||||
int handleDelete (std::string &);
|
||||
int handleStart (std::string &);
|
||||
int handleStop (std::string &);
|
||||
int handleColor (std::string &);
|
||||
int handleAnnotate (std::string &);
|
||||
int handleDuplicate (std::string &);
|
||||
void handleUndo ();
|
||||
#ifdef FEATURE_SHELL
|
||||
void handleShell ();
|
||||
@@ -85,27 +85,28 @@ int deltaAttributes (Task&);
|
||||
int deltaSubstitutions (Task&);
|
||||
|
||||
// edit.cpp
|
||||
std::string handleEdit ();
|
||||
int handleEdit (std::string &);
|
||||
|
||||
// report.cpp
|
||||
std::string shortUsage ();
|
||||
std::string longUsage ();
|
||||
std::string handleInfo ();
|
||||
std::string handleReportSummary ();
|
||||
std::string handleReportNext ();
|
||||
std::string handleReportHistory ();
|
||||
std::string handleReportGHistory ();
|
||||
std::string handleReportCalendar ();
|
||||
std::string handleReportStats ();
|
||||
std::string handleReportTimesheet ();
|
||||
int shortUsage (std::string &);
|
||||
int longUsage (std::string &);
|
||||
int handleInfo (std::string &);
|
||||
int handleReportSummary (std::string &);
|
||||
int handleReportNext (std::string &);
|
||||
int handleReportHistory (std::string &);
|
||||
int handleReportGHistory (std::string &);
|
||||
int handleReportCalendar (std::string &);
|
||||
int handleReportStats (std::string &);
|
||||
int handleReportTimesheet (std::string &);
|
||||
std::string getFullDescription (Task&);
|
||||
std::string getDueDate (Task&);
|
||||
|
||||
// custom.cpp
|
||||
std::string handleCustomReport (const std::string&);
|
||||
std::string runCustomReport (const std::string&, const std::string&,
|
||||
const std::string&, const std::string&,
|
||||
const std::string&, std::vector <Task>&);
|
||||
int handleCustomReport (const std::string&, std::string &);
|
||||
int runCustomReport (const std::string&, const std::string&,
|
||||
const std::string&, const std::string&,
|
||||
const std::string&, std::vector <Task>&,
|
||||
std::string&);
|
||||
void validReportColumns (const std::vector <std::string>&);
|
||||
void validSortColumns (const std::vector <std::string>&, const std::vector <std::string>&);
|
||||
|
||||
@@ -118,7 +119,7 @@ std::string colorizeFootnote (const std::string&);
|
||||
std::string colorizeDebug (const std::string&);
|
||||
|
||||
// import.cpp
|
||||
std::string handleImport ();
|
||||
int handleImport (std::string&);
|
||||
|
||||
// list template
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
extern Context context;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string shortUsage ()
|
||||
int shortUsage (std::string &outs)
|
||||
{
|
||||
Table table;
|
||||
|
||||
@@ -209,14 +209,19 @@ std::string shortUsage ()
|
||||
<< std::endl
|
||||
<< std::endl;
|
||||
|
||||
return out.str ();
|
||||
outs = out.str ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string longUsage ()
|
||||
int longUsage (std::string &outs)
|
||||
{
|
||||
std::string shortUsageString;
|
||||
std::stringstream out;
|
||||
out << shortUsage ()
|
||||
|
||||
(void)shortUsage(shortUsageString);
|
||||
|
||||
out << shortUsageString
|
||||
<< "ID is the numeric identifier displayed by the 'task list' command. "
|
||||
<< "You can specify multiple IDs for task commands, and multiple tasks "
|
||||
<< "will be affected. To specify multiple IDs make sure you use one "
|
||||
@@ -276,13 +281,15 @@ std::string longUsage ()
|
||||
<< " $ ! ' \" ( ) ; \\ ` * ? { } [ ] < > | & % # ~" << "\n"
|
||||
<< std::endl;
|
||||
|
||||
return out.str ();
|
||||
outs = out.str();
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Display all information for the given task.
|
||||
std::string handleInfo ()
|
||||
int handleInfo (std::string &outs)
|
||||
{
|
||||
int rc = 0;
|
||||
// Get all the tasks.
|
||||
std::vector <Task> tasks;
|
||||
context.tdb.lock (context.config.get ("locking", true));
|
||||
@@ -497,18 +504,22 @@ std::string handleInfo ()
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
if (! tasks.size ())
|
||||
if (! tasks.size ()) {
|
||||
out << "No matches." << std::endl;
|
||||
rc = 1;
|
||||
}
|
||||
|
||||
return out.str ();
|
||||
outs = out.str ();
|
||||
return rc;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Project Remaining Avg Age Complete 0% 100%
|
||||
// A 12 13d 55% XXXXXXXXXXXXX-----------
|
||||
// B 109 3d 12h 10% XXX---------------------
|
||||
std::string handleReportSummary ()
|
||||
int handleReportSummary (std::string &outs)
|
||||
{
|
||||
int rc = 0;
|
||||
// Scan the pending tasks.
|
||||
std::vector <Task> tasks;
|
||||
context.tdb.lock (context.config.get ("locking", true));
|
||||
@@ -648,10 +659,13 @@ std::string handleReportSummary ()
|
||||
<< table.rowCount ()
|
||||
<< (table.rowCount () == 1 ? " project" : " projects")
|
||||
<< std::endl;
|
||||
else
|
||||
else {
|
||||
out << "No projects." << std::endl;
|
||||
rc = 1;
|
||||
}
|
||||
|
||||
return out.str ();
|
||||
outs = out.str ();
|
||||
return rc;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -673,7 +687,7 @@ std::string handleReportSummary ()
|
||||
//
|
||||
// Make the "three" tasks a configurable number
|
||||
//
|
||||
std::string handleReportNext ()
|
||||
int handleReportNext (std::string &outs)
|
||||
{
|
||||
// Load report configuration.
|
||||
std::string columnList = context.config.get ("report.next.columns");
|
||||
@@ -718,7 +732,8 @@ std::string handleReportNext ()
|
||||
labelList,
|
||||
sortList,
|
||||
filterList,
|
||||
tasks);
|
||||
tasks,
|
||||
outs);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -744,8 +759,9 @@ time_t monthlyEpoch (const std::string& date)
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string handleReportHistory ()
|
||||
int handleReportHistory (std::string &outs)
|
||||
{
|
||||
int rc = 0;
|
||||
std::map <time_t, int> groups; // Represents any month with data
|
||||
std::map <time_t, int> addedGroup; // Additions by month
|
||||
std::map <time_t, int> completedGroup; // Completions by month
|
||||
@@ -891,15 +907,19 @@ std::string handleReportHistory ()
|
||||
out << optionalBlankLine ()
|
||||
<< table.render ()
|
||||
<< std::endl;
|
||||
else
|
||||
else {
|
||||
out << "No tasks." << std::endl;
|
||||
rc = 1;
|
||||
}
|
||||
|
||||
return out.str ();
|
||||
outs = out.str ();
|
||||
return rc;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string handleReportGHistory ()
|
||||
int handleReportGHistory (std::string &outs)
|
||||
{
|
||||
int rc = 0;
|
||||
std::map <time_t, int> groups; // Represents any month with data
|
||||
std::map <time_t, int> addedGroup; // Additions by month
|
||||
std::map <time_t, int> completedGroup; // Completions by month
|
||||
@@ -1087,14 +1107,17 @@ std::string handleReportGHistory ()
|
||||
else
|
||||
out << "Legend: + added, X completed, - deleted" << std::endl;
|
||||
}
|
||||
else
|
||||
else {
|
||||
out << "No tasks." << std::endl;
|
||||
rc = 1;
|
||||
}
|
||||
|
||||
return out.str ();
|
||||
outs = out.str ();
|
||||
return rc;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string handleReportTimesheet ()
|
||||
int handleReportTimesheet (std::string &outs)
|
||||
{
|
||||
// Scan the pending tasks.
|
||||
std::vector <Task> tasks;
|
||||
@@ -1264,7 +1287,8 @@ std::string handleReportTimesheet ()
|
||||
end -= 7 * 86400;
|
||||
}
|
||||
|
||||
return out.str ();
|
||||
outs = out.str ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -1376,9 +1400,9 @@ std::string renderMonths (
|
||||
row = 0;
|
||||
|
||||
// Loop through days in month and add to table.
|
||||
for (int d = 1; d <= daysInMonth.at (mpl); ++d)
|
||||
for (int d = 1; d <= daysInMonth[mpl]; ++d)
|
||||
{
|
||||
Date temp (months.at (mpl), d, years.at (mpl));
|
||||
Date temp (months[mpl], d, years[mpl]);
|
||||
int dow = temp.dayOfWeek ();
|
||||
int woy = temp.weekOfYear (weekStart);
|
||||
|
||||
@@ -1396,9 +1420,9 @@ std::string renderMonths (
|
||||
table.addCell (row, thisCol, d);
|
||||
|
||||
if ((context.config.get ("color", true) || context.config.get (std::string ("_forcecolor"), false)) &&
|
||||
today.day () == d &&
|
||||
today.month () == months.at (mpl) &&
|
||||
today.year () == years.at (mpl))
|
||||
today.day () == d &&
|
||||
today.month () == months[mpl] &&
|
||||
today.year () == years[mpl])
|
||||
table.setCellFg (row, thisCol, Text::cyan);
|
||||
|
||||
foreach (task, all)
|
||||
@@ -1410,8 +1434,8 @@ std::string renderMonths (
|
||||
|
||||
if ((context.config.get ("color", true) || context.config.get (std::string ("_forcecolor"), false)) &&
|
||||
due.day () == d &&
|
||||
due.month () == months.at (mpl) &&
|
||||
due.year () == years.at (mpl))
|
||||
due.month () == months[mpl] &&
|
||||
due.year () == years[mpl])
|
||||
{
|
||||
table.setCellFg (row, thisCol, Text::black);
|
||||
table.setCellBg (row, thisCol, due < today ? Text::on_red : Text::on_yellow);
|
||||
@@ -1423,7 +1447,7 @@ std::string renderMonths (
|
||||
int eow = 6;
|
||||
if (weekStart == 1)
|
||||
eow = 0;
|
||||
if (dow == eow && d < daysInMonth.at (mpl))
|
||||
if (dow == eow && d < daysInMonth[mpl])
|
||||
row++;
|
||||
}
|
||||
}
|
||||
@@ -1432,7 +1456,7 @@ std::string renderMonths (
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string handleReportCalendar ()
|
||||
int handleReportCalendar (std::string &outs)
|
||||
{
|
||||
// Each month requires 28 text columns width. See how many will actually
|
||||
// fit. But if a preference is specified, and it fits, use it.
|
||||
@@ -1604,11 +1628,12 @@ std::string handleReportCalendar ()
|
||||
<< optionalBlankLine ()
|
||||
<< std::endl;
|
||||
|
||||
return out.str ();
|
||||
outs = out.str ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string handleReportStats ()
|
||||
int handleReportStats (std::string &outs)
|
||||
{
|
||||
std::stringstream out;
|
||||
|
||||
@@ -1836,7 +1861,8 @@ std::string handleReportStats ()
|
||||
<< table.render ()
|
||||
<< optionalBlankLine ();
|
||||
|
||||
return out.str ();
|
||||
outs = out.str ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -40,7 +40,7 @@ if (open my $fh, '>', 'basic.rc')
|
||||
|
||||
# Test the usage command.
|
||||
my $output = qx{../task rc:basic.rc};
|
||||
like ($output, qr/You must specify a command, or a task ID to modify/, 'missing command and ID');
|
||||
like ($output, qr/You must specify a command, or a task ID to modify/m, 'missing command and ID');
|
||||
|
||||
# Test the version command.
|
||||
$output = qx{../task rc:basic.rc version};
|
||||
|
||||
62
src/tests/feature.exit.t
Executable file
62
src/tests/feature.exit.t
Executable file
@@ -0,0 +1,62 @@
|
||||
#! /usr/bin/perl
|
||||
################################################################################
|
||||
## task - a command line task list manager.
|
||||
##
|
||||
## Copyright 2006 - 2009, Paul Beckingham.
|
||||
## All rights reserved.
|
||||
##
|
||||
## This program is free software; you can redistribute it and/or modify it under
|
||||
## the terms of the GNU General Public License as published by the Free Software
|
||||
## Foundation; either version 2 of the License, or (at your option) any later
|
||||
## version.
|
||||
##
|
||||
## This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
## FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
## details.
|
||||
##
|
||||
## You should have received a copy of the GNU General Public License along with
|
||||
## this program; if not, write to the
|
||||
##
|
||||
## Free Software Foundation, Inc.,
|
||||
## 51 Franklin Street, Fifth Floor,
|
||||
## Boston, MA
|
||||
## 02110-1301
|
||||
## USA
|
||||
##
|
||||
################################################################################
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Test::More tests => 7;
|
||||
|
||||
# Create the rc file.
|
||||
if (open my $fh, '>', 'exit.rc')
|
||||
{
|
||||
print $fh "data.location=.\n",
|
||||
"confirmation=no\n";
|
||||
close $fh;
|
||||
ok (-r 'exit.rc', 'Created exit.rc');
|
||||
}
|
||||
|
||||
qx{../task rc:exit.rc add foo};
|
||||
my $exit_good = system ('../task rc:exit.rc ls foo 2>&1 >>/dev/null');
|
||||
is ($exit_good, 0, 'task returns 0 on success');
|
||||
my $exit_bad = system ('../task rc:exit.rc ls bar 2>&1 >>/dev/null');
|
||||
isnt ($exit_bad, 0, 'task returns non-zero on failure');
|
||||
|
||||
# Cleanup.
|
||||
unlink 'pending.data';
|
||||
ok (!-r 'pending.data', 'Removed pending.data');
|
||||
|
||||
unlink 'completed.data';
|
||||
ok (!-r 'completed.data', 'Removed completed.data');
|
||||
|
||||
unlink 'undo.data';
|
||||
ok (!-r 'undo.data', 'Removed undo.data');
|
||||
|
||||
unlink 'exit.rc';
|
||||
ok (!-r 'exit.rc', 'Removed exit.rc');
|
||||
|
||||
exit 0;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#! /bin/bash
|
||||
#! /bin/sh
|
||||
|
||||
date > all.log
|
||||
|
||||
@@ -14,7 +14,7 @@ END=`tail -1 all.log`
|
||||
OS=`uname`
|
||||
|
||||
case $OS in
|
||||
Darwin)
|
||||
Darwin | FreeBSD)
|
||||
STARTEPOCH=`date -j -f "%a %b %d %T %Z %Y" "${START}" "+%s"`
|
||||
ENDEPOCH=`date -j -f "%a %b %d %T %Z %Y" "${END}" "+%s"`
|
||||
;;
|
||||
|
||||
24
src/text.cpp
24
src/text.cpp
@@ -209,7 +209,7 @@ std::string commify (const std::string& data)
|
||||
int i;
|
||||
for (int i = 0; i < (int) data.length (); ++i)
|
||||
{
|
||||
if (::isdigit (data[i]))
|
||||
if (isdigit (data[i]))
|
||||
end = i;
|
||||
|
||||
if (data[i] == '.')
|
||||
@@ -227,11 +227,11 @@ std::string commify (const std::string& data)
|
||||
int consecutiveDigits = 0;
|
||||
for (; i >= 0; --i)
|
||||
{
|
||||
if (::isdigit (data[i]))
|
||||
if (isdigit (data[i]))
|
||||
{
|
||||
result += data[i];
|
||||
|
||||
if (++consecutiveDigits == 3 && i && ::isdigit (data[i - 1]))
|
||||
if (++consecutiveDigits == 3 && i && isdigit (data[i - 1]))
|
||||
{
|
||||
result += ',';
|
||||
consecutiveDigits = 0;
|
||||
@@ -251,11 +251,11 @@ std::string commify (const std::string& data)
|
||||
int consecutiveDigits = 0;
|
||||
for (; i >= 0; --i)
|
||||
{
|
||||
if (::isdigit (data[i]))
|
||||
if (isdigit (data[i]))
|
||||
{
|
||||
result += data[i];
|
||||
|
||||
if (++consecutiveDigits == 3 && i && ::isdigit (data[i - 1]))
|
||||
if (++consecutiveDigits == 3 && i && isdigit (data[i - 1]))
|
||||
{
|
||||
result += ',';
|
||||
consecutiveDigits = 0;
|
||||
@@ -279,8 +279,8 @@ std::string lowerCase (const std::string& input)
|
||||
{
|
||||
std::string output = input;
|
||||
for (int i = 0; i < (int) input.length (); ++i)
|
||||
if (::isupper (input[i]))
|
||||
output[i] = ::tolower (input[i]);
|
||||
if (isupper (input[i]))
|
||||
output[i] = tolower (input[i]);
|
||||
|
||||
return output;
|
||||
}
|
||||
@@ -290,8 +290,8 @@ std::string upperCase (const std::string& input)
|
||||
{
|
||||
std::string output = input;
|
||||
for (int i = 0; i < (int) input.length (); ++i)
|
||||
if (::islower (input[i]))
|
||||
output[i] = ::toupper (input[i]);
|
||||
if (islower (input[i]))
|
||||
output[i] = toupper (input[i]);
|
||||
|
||||
return output;
|
||||
}
|
||||
@@ -302,7 +302,7 @@ std::string ucFirst (const std::string& input)
|
||||
std::string output = input;
|
||||
|
||||
if (output.length () > 0)
|
||||
output[0] = ::toupper (output[0]);
|
||||
output[0] = toupper (output[0]);
|
||||
|
||||
return output;
|
||||
}
|
||||
@@ -352,7 +352,7 @@ void guess (
|
||||
bool digitsOnly (const std::string& input)
|
||||
{
|
||||
for (size_t i = 0; i < input.length (); ++i)
|
||||
if (!::isdigit (input[i]))
|
||||
if (!isdigit (input[i]))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@@ -362,7 +362,7 @@ bool digitsOnly (const std::string& input)
|
||||
bool noSpaces (const std::string& input)
|
||||
{
|
||||
for (size_t i = 0; i < input.length (); ++i)
|
||||
if (::isspace (input[i]))
|
||||
if (isspace (input[i]))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
||||
@@ -64,7 +64,7 @@ bool confirm (const std::string& question)
|
||||
<< " ";
|
||||
|
||||
std::getline (std::cin, answer);
|
||||
answer = lowerCase (trim (answer));
|
||||
answer = std::cin.eof() ? "no" : lowerCase (trim (answer));
|
||||
}
|
||||
while (answer != "y" && // TODO i18n
|
||||
answer != "ye" && // TODO i18n
|
||||
|
||||
Reference in New Issue
Block a user