Code Cleanup

- Fixed comments, compilation warnings.
- Decomposed Context::initialize into several, single-purpose methods.
- Replaced Context::initialize with Context::initialize2.
This commit is contained in:
Paul Beckingham 2011-05-24 19:35:59 -04:00
parent a20a4da412
commit d892a0cbd2
10 changed files with 217 additions and 534 deletions

View file

@ -45,19 +45,22 @@
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
Context::Context () Context::Context ()
: config () : program ("")
, rc_file ()
, data_dir ()
, config ()
, filter () , filter ()
, sequence () , sequence ()
, subst () , subst ()
, task () , task ()
, tdb () , tdb ()
, tdb2 () , tdb2 ()
, program ("")
, commandLine ("") , commandLine ("")
, file_override ("") , file_override ("")
, var_overrides ("") , var_overrides ("")
, cmd () , cmd ()
, dom () , dom ()
, determine_color_use (true)
, use_color (true) , use_color (true)
, verbosity_legacy (false) , verbosity_legacy (false)
, inShadow (false) , inShadow (false)
@ -72,69 +75,50 @@ Context::~Context ()
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void Context::initialize2 (int argc, char** argv) void Context::initialize (int argc, char** argv)
{ {
Timer t ("Context::initialize2"); Timer t ("Context::initialize");
// Capture the args. // char** argv --> std::vector <std::string> Context::args.
for (int i = 0; i < argc; ++i) captureCommandLineArgs (argc, argv);
{
if (i == 0)
{
program = argv[i];
std::string::size_type cal = program.find ("/cal");
if (program == "cal" ||
(cal != std::string::npos && program.length () == cal + 4))
args.push_back ("calendar");
}
else
args.push_back (argv[i]);
}
// Capture any stdin args. // echo one two -- three | task zero --> task zero one two
struct timeval tv; // 'three' is left in the input buffer.
fd_set fds; appendPipedArgs ();
tv.tv_sec = 0;
tv.tv_usec = 0;
FD_ZERO (&fds);
FD_SET (STDIN_FILENO, &fds);
select (STDIN_FILENO + 1, &fds, NULL, NULL, &tv);
if (FD_ISSET (0, &fds))
{
std::string arg;
while (std::cin >> arg)
{
if (arg == "--")
break;
args.push_back (arg); // Assume default .taskrc and .task locations.
} assumeLocations ();
}
// TODO Scan for rc:<file> overrides --> apply. // Process 'rc:<file>' command line override, and remove the argument from the
// Context::args.
overrideRCFile ();
// Load the configuration file from the home directory. If the file cannot // Dump any existing values and load rc file.
// be found, offer to create a sample one. config.clear ();
loadCorrectConfigFile (); config.load (rc_file);
// The data location, Context::data_dir, is determined from the assumed
// location (~/.task), or set by data.location in the config file, or
// overridden by rc.data.location on the command line.
determineDataLocation ();
// Create missing config file and data directory, if necessary.
createDefaultConfig ();
// Apply rc overrides to Context::config.
applyOverrides ();
// Handle Aliases.
loadAliases (); loadAliases ();
resolveAliases (); resolveAliases ();
// Combine command line into one string. // Combine command line into one string.
join (commandLine, " ", args); join (commandLine, " ", args);
// When redirecting output to a file, do not use color. // Initialize the color rules, if necessary.
if (!isatty (fileno (stdout))) if (color ())
{
config.set ("detection", "off");
if (! config.getBoolean ("_forcecolor"))
config.set ("color", "off");
}
if (config.getBoolean ("color"))
initializeColorRules (); initializeColorRules ();
// Instantiate built-in command objects. // Instantiate built-in command objects.
Command::factory (commands); Command::factory (commands);
@ -142,42 +126,6 @@ void Context::initialize2 (int argc, char** argv)
// TODO Instantiate default command object. // TODO Instantiate default command object.
// TODO Instantiate extension UDA objects. // TODO Instantiate extension UDA objects.
// TODO Instantiate extension format objects. // TODO Instantiate extension format objects.
// TODO Hook: on-launch
}
////////////////////////////////////////////////////////////////////////////////
void Context::initialize (int argc, char** argv)
{
// Capture the args.
// ...
// Capture any stdin args.
// ...
initialize ();
// Hook system init, plus post-start event occurring at the first possible
// moment after hook initialization.
hooks.initialize ();
hooks.trigger ("on-launch");
}
////////////////////////////////////////////////////////////////////////////////
void Context::initialize ()
{
Timer t ("Context::initialize");
// Load the configuration file from the home directory. If the file cannot
// be found, offer to create a sample one.
// ...
// Resolve aliases.
// ...
// When redirecting output to a file, do not use color.
// ...
Directory location (config.get ("data.location"));
// If there is a locale variant (en-US.<variant>), then strip it. // If there is a locale variant (en-US.<variant>), then strip it.
std::string locale = config.get ("locale"); std::string locale = config.get ("locale");
@ -185,12 +133,14 @@ void Context::initialize ()
if (period != std::string::npos) if (period != std::string::npos)
locale = locale.substr (0, period); locale = locale.substr (0, period);
// init TDB. // Initialize the database.
tdb.clear (); tdb.clear ();
std::vector <std::string> all; tdb.location (data_dir);
split (all, location, ',');
foreach (path, all) // Hook system init, plus post-start event occurring at the first possible
tdb.location (*path); // moment after hook initialization.
hooks.initialize ();
hooks.trigger ("on-launch");
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -271,14 +221,22 @@ int Context::dispatch2 (std::string &out)
std::vector <std::string> matches; std::vector <std::string> matches;
if (autoComplete (*arg, keywords, matches) == 1) if (autoComplete (*arg, keywords, matches) == 1)
{ {
Command* c = commands[matches[0]]; if (*arg != matches[0])
if (! c->read_only ()) debug ("Context::dispatch2 parse keyword '" + *arg + "' --> '" + matches[0] + "'");
tdb.gc (); else
debug ("Context::dispatch2 parse keyword '" + *arg + "'");
return c->execute (commandLine, out); Command* c = commands[matches[0]];
if (c->displays_id ())
tdb.gc ();
return c->execute (commandLine, out);
} }
} }
// TODO When ::dispatch is eliminated, show usage on unrecognized command.
// commands["help"]->execute (commandLine, out);
return 1; return 1;
} }
@ -291,7 +249,6 @@ int Context::dispatch (std::string &out)
// TODO Chain-of-command pattern dispatch. // TODO Chain-of-command pattern dispatch.
if (cmd.command == "projects") { rc = handleProjects (out); } 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 == "colors") { rc = handleColor (out); }
else if (cmd.command == "version") { rc = handleVersion (out); } else if (cmd.command == "version") { rc = handleVersion (out); }
else if (cmd.command == "config") { rc = handleConfig (out); } else if (cmd.command == "config") { rc = handleConfig (out); }
@ -347,11 +304,10 @@ int Context::dispatch (std::string &out)
sequence.size ()) { rc = handleModify (out); } sequence.size ()) { rc = handleModify (out); }
// Commands that display IDs and therefore need TDB::gc first. // Commands that display IDs and therefore need TDB::gc first.
else if (cmd.validCustom (cmd.command)) { if (!inShadow) tdb.gc (); // ...
rc = handleCustomReport (cmd.command, out); }// ...
// If the command is not recognized, display usage. // If the command is not recognized, display usage.
else { rc = shortUsage (out); } else { rc = commands["help"]->execute (commandLine, out); }
// Only update the shadow file if such an update was not suppressed (shadow), // Only update the shadow file if such an update was not suppressed (shadow),
if ((cmd.isWriteCommand () || if ((cmd.isWriteCommand () ||
@ -365,8 +321,35 @@ int Context::dispatch (std::string &out)
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
bool Context::color () bool Context::color ()
{ {
return config.getBoolean ("color") || if (determine_color_use)
config.getBoolean ("_forcecolor"); {
// What the config says.
use_color = config.getBoolean ("color");
// Only tty's support color.
if (! isatty (fileno (stdout)))
{
// No ioctl.
config.set ("detection", "off");
config.set ("color", "off");
// Files don't get color.
use_color = false;
}
// Override.
if (config.getBoolean ("_forcecolor"))
{
config.set ("color", "on");
use_color = true;
}
// No need to go through this again.
determine_color_use = false;
}
// Cached result.
return use_color;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -424,7 +407,7 @@ void Context::shadow ()
split (args, command, ' '); split (args, command, ' ');
initialize (); //initialize ();
config.set ("detection", "off"); config.set ("detection", "off");
config.set ("color", "off"); config.set ("color", "off");
@ -451,36 +434,6 @@ void Context::shadow ()
} }
} }
////////////////////////////////////////////////////////////////////////////////
// Only allows aliases 10 deep.
std::string Context::canonicalize (const std::string& input) const
{
std::string canonical = input;
// First try to autocomplete the alias.
std::vector <std::string> options;
std::vector <std::string> matches;
foreach (name, aliases)
options.push_back (name->first);
autoComplete (input, options, matches);
if (matches.size () == 1)
{
canonical = matches[0];
// Follow the chain.
int i = 10; // Safety valve.
std::map <std::string, std::string>::const_iterator found;
while ((found = aliases.find (canonical)) != aliases.end () && i-- > 0)
canonical = found->second;
if (i < 1)
return input;
}
return canonical;
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void Context::disallowModification () const void Context::disallowModification () const
{ {
@ -497,23 +450,24 @@ void Context::disallowModification () const
// Takes a vector of args (foo, rc.name:value, bar), extracts any rc.name:value // Takes a vector of args (foo, rc.name:value, bar), extracts any rc.name:value
// args and sets the name/value in context.config, returning only the plain args // args and sets the name/value in context.config, returning only the plain args
// (foo, bar) as output. // (foo, bar) as output.
void Context::applyOverrides ( void Context::applyOverrides ()
const std::vector <std::string>& input,
std::vector <std::string>& output)
{ {
std::vector <std::string> filtered;
bool foundTerminator = false; bool foundTerminator = false;
foreach (in, input)
std::vector <std::string>::iterator arg;
for (arg = args.begin (); arg != args.end (); ++arg)
{ {
if (*in == "--") if (*arg == "--")
{ {
foundTerminator = true; foundTerminator = true;
output.push_back (*in); filtered.push_back (*arg);
} }
else if (!foundTerminator && in->substr (0, 3) == "rc.") else if (!foundTerminator && arg->substr (0, 3) == "rc.")
{ {
std::string name; std::string name;
std::string value; std::string value;
Nibbler n (*in); Nibbler n (*arg);
if (n.getLiteral ("rc.") && // rc. if (n.getLiteral ("rc.") && // rc.
n.getUntilOneOf (":=", name) && // xxx n.getUntilOneOf (":=", name) && // xxx
n.skipN (1)) // : n.skipN (1)) // :
@ -521,60 +475,114 @@ void Context::applyOverrides (
n.getUntilEOS (value); // Don't care if it's blank. n.getUntilEOS (value); // Don't care if it's blank.
config.set (name, value); config.set (name, value);
var_overrides += " " + *in; footnote ("Configuration override " + arg->substr (3));
footnote ("Configuration override " + in->substr (3));
// Overrides are retained for potential use by the default command.
var_overrides += " " + *arg;
} }
else else
footnote ("Problem with override: " + *in); footnote ("Problem with override: " + *arg);
} }
else else
output.push_back (*in); filtered.push_back (*arg);
}
// Overwrite args with the filtered subset.
args = filtered;
}
////////////////////////////////////////////////////////////////////////////////
void Context::captureCommandLineArgs (int argc, char** argv)
{
for (int i = 0; i < argc; ++i)
{
if (i == 0)
{
program = argv[i];
std::string::size_type cal = program.find ("/cal");
if (program == "cal" ||
(cal != std::string::npos && program.length () == cal + 4))
args.push_back ("calendar");
}
else
args.push_back (argv[i]);
} }
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void Context::loadCorrectConfigFile () void Context::appendPipedArgs ()
{
// Capture any stdin args.
struct timeval tv;
fd_set fds;
tv.tv_sec = 0;
tv.tv_usec = 0;
FD_ZERO (&fds);
FD_SET (STDIN_FILENO, &fds);
select (STDIN_FILENO + 1, &fds, NULL, NULL, &tv);
if (FD_ISSET (0, &fds))
{
std::string arg;
while (std::cin >> arg)
{
if (arg == "--")
break;
args.push_back (arg);
}
}
}
////////////////////////////////////////////////////////////////////////////////
void Context::assumeLocations ()
{ {
// Set up default locations. // Set up default locations.
struct passwd* pw = getpwuid (getuid ()); struct passwd* pw = getpwuid (getuid ());
if (!pw) if (!pw)
throw std::string ("Could not read home directory from the passwd file."); throw std::string ("Could not read home directory from the passwd file.");
std::string home = pw->pw_dir; home_dir = pw->pw_dir;
File rc (home + "/.taskrc"); rc_file = File (home_dir + "/.taskrc");
Directory data (home + "./task"); data_dir = Directory (home_dir + "./task");
}
// Is there an file_override for rc:? ////////////////////////////////////////////////////////////////////////////////
foreach (arg, args) void Context::overrideRCFile ()
{
// Is there an override for rc:<file>?
std::vector <std::string>::iterator arg;
for (arg = args.begin (); arg != args.end (); ++arg)
{ {
// Nothing after -- is to be interpreted in any way.
if (*arg == "--") if (*arg == "--")
break; break;
else if (arg->substr (0, 3) == "rc:") else if (arg->substr (0, 3) == "rc:")
{ {
file_override = *arg; file_override = *arg;
rc = File (arg->substr (3)); rc_file = File (arg->substr (3));
home = rc; home_dir = rc_file;
std::string::size_type last_slash = rc.data.rfind ("/"); std::string::size_type last_slash = rc_file.data.rfind ("/");
if (last_slash != std::string::npos) if (last_slash != std::string::npos)
home = rc.data.substr (0, last_slash); home_dir = rc_file.data.substr (0, last_slash);
else else
home = "."; home_dir = ".";
args.erase (arg); args.erase (arg);
header ("Using alternate .taskrc file " + rc.data); // TODO i18n header ("Using alternate .taskrc file " + rc_file.data); // TODO i18n
break; break; // Must break - iterator is dead.
} }
} }
}
// Load rc file. ////////////////////////////////////////////////////////////////////////////////
config.clear (); // Dump current values. void Context::determineDataLocation ()
config.load (rc); // Load new file. {
if (config.get ("data.location") != "") if (config.get ("data.location") != "")
data = Directory (config.get ("data.location")); data_dir = Directory (config.get ("data.location"));
// Are there any var_overrides for data.location? // Are there any overrides for data.location?
foreach (arg, args) foreach (arg, args)
{ {
if (*arg == "--") if (*arg == "--")
@ -582,33 +590,32 @@ void Context::loadCorrectConfigFile ()
else if (arg->substr (0, 16) == "rc.data.location" && else if (arg->substr (0, 16) == "rc.data.location" &&
((*arg)[16] == ':' || (*arg)[16] == '=')) ((*arg)[16] == ':' || (*arg)[16] == '='))
{ {
data = Directory (arg->substr (17)); data_dir = Directory (arg->substr (17));
header ("Using alternate data.location " + data.data); // TODO i18n header ("Using alternate data.location " + data_dir.data); // TODO i18n
break; break;
} }
} }
}
////////////////////////////////////////////////////////////////////////////////
void Context::createDefaultConfig ()
{
// Do we need to create a default rc? // Do we need to create a default rc?
if (! rc.exists ()) if (! rc_file.exists ())
{ {
if (!confirm ("A configuration file could not be found in " // TODO i18n if (!confirm ("A configuration file could not be found in " // TODO i18n
+ home + home_dir
+ "\n\n" + "\n\n"
+ "Would you like a sample " + "Would you like a sample "
+ rc.data + rc_file.data
+ " created, so taskwarrior can proceed?")) + " created, so taskwarrior can proceed?"))
throw std::string ("Cannot proceed without rc file."); throw std::string ("Cannot proceed without rc file.");
config.createDefaultRC (rc, data); config.createDefaultRC (rc_file, data_dir);
} }
// Create data location, if necessary. // Create data location, if necessary.
config.createDefaultData (data); config.createDefaultData (data_dir);
// Apply rc overrides.
std::vector <std::string> filtered;
applyOverrides (args, filtered);
args = filtered;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -892,7 +899,7 @@ void Context::parse (
file_override = ""; file_override = "";
var_overrides = ""; var_overrides = "";
footnotes.clear (); footnotes.clear ();
initialize (); //initialize ();
parse (args, cmd, task, sequence, subst, filter); parse (args, cmd, task, sequence, subst, filter);
} }
else else

View file

@ -49,10 +49,8 @@ public:
Context (const Context&); Context (const Context&);
Context& operator= (const Context&); Context& operator= (const Context&);
void initialize (int, char**); // all startup TODO Obsolete void initialize (int, char**); // all startup
void initialize2 (int, char**); // all startup int run ();
void initialize (); // for reinitializing
int run (); // task classic
int dispatch2 (std::string&); // command handler dispatch int dispatch2 (std::string&); // command handler dispatch
int dispatch (std::string&); // command handler dispatch int dispatch (std::string&); // command handler dispatch
void shadow (); // shadow file update void shadow (); // shadow file update
@ -72,13 +70,17 @@ public:
void parse (std::vector <std::string>&, Cmd&, Task&, Sequence&, Subst&, Filter&); void parse (std::vector <std::string>&, Cmd&, Task&, Sequence&, Subst&, Filter&);
void clear (); void clear ();
std::string canonicalize (const std::string&) const;
void disallowModification () const; void disallowModification () const;
void applyOverrides (const std::vector <std::string>&, std::vector <std::string>&); void applyOverrides ();
void decomposeSortField (const std::string&, std::string&, bool&); void decomposeSortField (const std::string&, std::string&, bool&);
private: private:
void loadCorrectConfigFile (); void captureCommandLineArgs (int, char**);
void appendPipedArgs ();
void assumeLocations ();
void overrideRCFile ();
void determineDataLocation ();
void createDefaultConfig ();
void loadAliases (); void loadAliases ();
void resolveAliases (); void resolveAliases ();
void autoFilter (Att&, Filter&); void autoFilter (Att&, Filter&);
@ -86,15 +88,19 @@ private:
void updateXtermTitle (); void updateXtermTitle ();
public: public:
std::string program;
std::vector <std::string> args;
std::string home_dir;
File rc_file;
Path data_dir;
Config config; Config config;
Filter filter; Filter filter;
Sequence sequence; Sequence sequence;
Subst subst; Subst subst;
Task task; Task task;
TDB tdb; // TODO Obsolete TDB tdb; // TODO Obsolete
TDB2 tdb2; TDB2 tdb2;
std::string program;
std::vector <std::string> args;
std::string commandLine; std::string commandLine;
std::string file_override; std::string file_override;
std::string var_overrides; std::string var_overrides;
@ -104,6 +110,9 @@ public:
std::vector <std::string> tagRemovals; std::vector <std::string> tagRemovals;
Hooks hooks; Hooks hooks;
DOM dom; DOM dom;
// Color
bool determine_color_use;
bool use_color; bool use_color;
bool verbosity_legacy; bool verbosity_legacy;

View file

@ -182,7 +182,7 @@ json::array* json::array::parse (Nibbler& nibbler)
json::array* arr = new json::array (); json::array* arr = new json::array ();
json::value* value; json::value* value;
if (value = json::value::parse (n)) if ((value = json::value::parse (n)))
{ {
arr->push_back (value); arr->push_back (value);
value = NULL; // Not a leak. Looks like a leak. value = NULL; // Not a leak. Looks like a leak.
@ -191,7 +191,7 @@ json::array* json::array::parse (Nibbler& nibbler)
{ {
n.skipWS (); n.skipWS ();
if (value = json::value::parse (n)) if ((value = json::value::parse (n)))
{ {
arr->push_back (value); arr->push_back (value);
n.skipWS (); n.skipWS ();
@ -323,7 +323,7 @@ bool json::object::parse_pair (
if (n.skip (':')) if (n.skip (':'))
{ {
n.skipWS (); n.skipWS ();
if (val = json::value::parse (n)) if ((val = json::value::parse (n)))
{ {
nibbler = n; nibbler = n;
return true; return true;

View file

@ -45,29 +45,12 @@ Variant::Variant (const Variant& other)
// Explicitly copy only the relevant type. This saves memory. // Explicitly copy only the relevant type. This saves memory.
switch (mType) switch (mType)
{ {
case v_boolean: case v_boolean: mBool = other.mBool; break;
mBool = other.mBool; case v_integer: mInteger = other.mInteger; break;
break; case v_double: mDouble = other.mDouble; break;
case v_string: mString = other.mString; break;
case v_integer: case v_date: mDate = other.mDate; break;
mInteger = other.mInteger; case v_duration: mDuration = other.mDuration; break;
break;
case v_double:
mDouble = other.mDouble;
break;
case v_string:
mString = other.mString;
break;
case v_date:
mDate = other.mDate;
break;
case v_duration:
mDuration = other.mDuration;
break;
} }
} }
@ -464,7 +447,7 @@ Variant& Variant::operator< (const Variant& other)
switch (mType) switch (mType)
{ {
case v_boolean: case v_boolean:
throw std::string ("Cannot perform relationally compare Boolean types"); throw std::string ("Cannot perform relational compare Boolean types");
break; break;
case v_integer: case v_integer:
@ -501,7 +484,7 @@ Variant& Variant::operator> (const Variant& other)
switch (mType) switch (mType)
{ {
case v_boolean: case v_boolean:
throw std::string ("Cannot perform relationally compare Boolean types"); throw std::string ("Cannot perform relational compare Boolean types");
break; break;
case v_integer: case v_integer:

View file

@ -331,78 +331,6 @@ int handleCompletionProjects (std::string& outs)
return 0; return 0;
} }
////////////////////////////////////////////////////////////////////////////////
int handleTags (std::string& outs)
{
int rc = 0;
std::stringstream out;
std::vector <Task> tasks;
context.tdb.lock (context.config.getBoolean ("locking"));
int quantity = 0;
if (context.config.getBoolean ("list.all.tags"))
quantity += context.tdb.load (tasks, context.filter);
else
quantity += context.tdb.loadPending (tasks, context.filter);
context.tdb.commit ();
context.tdb.unlock ();
// Scan all the tasks for their project name, building a map using project
// names as keys.
std::map <std::string, int> unique;
foreach (t, tasks)
{
std::vector <std::string> tags;
t->getTags (tags);
foreach (tag, tags)
if (unique.find (*tag) != unique.end ())
unique[*tag]++;
else
unique[*tag] = 1;
}
if (unique.size ())
{
// Render a list of tags names from the map.
ViewText view;
view.width (context.getWidth ());
view.add (Column::factory ("string", "Tag"));
view.add (Column::factory ("string.right", "Count"));
Color bold ("bold");
bool special = false;
foreach (i, unique)
{
// Highlight the special tags.
special = (context.color () &&
(i->first == "nocolor" ||
i->first == "nonag" ||
i->first == "next")) ? true : false;
int row = view.addRow ();
view.set (row, 0, i->first, special ? bold : Color ());
view.set (row, 1, i->second, special ? bold : Color ());
}
out << optionalBlankLine ()
<< view.render ()
<< optionalBlankLine ()
<< unique.size ()
<< (unique.size () == 1 ? " tag" : " tags")
<< " (" << quantity << (quantity == 1 ? " task" : " tasks") << ")\n";
}
else
{
out << "No tags.\n";
rc = 1;
}
outs = out.str ();
return rc;
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
int handleCompletionTags (std::string& outs) int handleCompletionTags (std::string& outs)
{ {
@ -2302,8 +2230,7 @@ void handleShell ()
split (args, decoratedCommand, ' '); split (args, decoratedCommand, ' ');
foreach (arg, args) context.args.push_back (*arg); foreach (arg, args) context.args.push_back (*arg);
context.initialize2 (0, NULL); context.initialize (0, NULL);
context.initialize ();
context.run (); context.run ();
} }

View file

@ -63,7 +63,6 @@ int main (int argc, char** argv)
try try
{ {
context.initialize2 (argc, argv);
context.initialize (argc, argv); context.initialize (argc, argv);
status = context.run (); status = context.run ();
} }

View file

@ -57,7 +57,6 @@ int handleDone (std::string&);
int handleModify (std::string&); int handleModify (std::string&);
int handleProjects (std::string&); int handleProjects (std::string&);
int handleCompletionProjects (std::string&); int handleCompletionProjects (std::string&);
int handleTags (std::string&);
int handleCompletionTags (std::string&); int handleCompletionTags (std::string&);
int handleCompletionCommands (std::string&); int handleCompletionCommands (std::string&);
int handleCompletionIDs (std::string&); int handleCompletionIDs (std::string&);
@ -98,7 +97,6 @@ void handleDiagnostics (std::string&);
int handleEdit (std::string&); int handleEdit (std::string&);
// report.cpp // report.cpp
int shortUsage (std::string&);
int handleInfo (std::string&); int handleInfo (std::string&);
int handleReportSummary (std::string&); int handleReportSummary (std::string&);
int handleReportCalendar (std::string&); int handleReportCalendar (std::string&);
@ -120,12 +118,6 @@ int handleReportHistoryAnnual (std::string&);
int handleReportGHistoryMonthly (std::string&); int handleReportGHistoryMonthly (std::string&);
int handleReportGHistoryAnnual (std::string&); int handleReportGHistoryAnnual (std::string&);
// custom.cpp
int handleCustomReport (const std::string&, std::string&);
void validateReportColumns (const std::vector <std::string>&);
void validateSortColumns (const std::vector <std::string>&);
void getLimits (const std::string&, int&, int&);
// rules.cpp // rules.cpp
void initializeColorRules (); void initializeColorRules ();
void autoColorize (Task&, Color&); void autoColorize (Task&, Color&);

View file

@ -51,240 +51,6 @@ static void countTasks (const std::vector <Task>&, const std::string&, const std
extern Context context; extern Context context;
////////////////////////////////////////////////////////////////////////////////
int shortUsage (std::string& outs)
{
ViewText view;
view.width (context.getWidth ());
view.add (Column::factory ("string", ""));
view.add (Column::factory ("string", ""));
view.add (Column::factory ("string", ""));
int row = view.addRow ();
view.set (row, 0, "Usage:");
view.set (row, 1, "task");
row = view.addRow ();
view.set (row, 1, "task add [tags] [attrs] desc...");
view.set (row, 2, "Adds a new task.");
row = view.addRow ();
view.set (row, 1, "task log [tags] [attrs] desc...");
view.set (row, 2, "Adds a new task that is already completed.");
row = view.addRow ();
view.set (row, 1, "task append ID [tags] [attrs] desc...");
view.set (row, 2, "Appends more description to an existing task.");
row = view.addRow ();
view.set (row, 1, "task prepend ID [tags] [attrs] desc...");
view.set (row, 2, "Prepends more description to an existing task.");
row = view.addRow ();
view.set (row, 1, "task annotate ID desc...");
view.set (row, 2, "Adds an annotation to an existing task.");
row = view.addRow ();
view.set (row, 1, "task denotate ID desc...");
view.set (row, 2, "Deletes an annotation of an existing task.");
row = view.addRow ();
view.set (row, 1, "task ID [tags] [attrs] [desc...]");
view.set (row, 2, "Modifies the existing task with provided arguments.");
row = view.addRow ();
view.set (row, 1, "task ID /from/to/g");
view.set (row, 2, "Performs substitution on the task description and "
"annotations. The 'g' is optional, and causes "
"substitutions for all matching text, not just the "
"first occurrence.");
row = view.addRow ();
view.set (row, 1, "task ID");
view.set (row, 2, "Specifying an ID without a command invokes the 'info' command.");
row = view.addRow ();
view.set (row, 1, "task edit ID");
view.set (row, 2, "Launches an editor to let you modify all aspects of a task directly, therefore it is to be used carefully.");
row = view.addRow ();
view.set (row, 1, "task undo");
view.set (row, 2, "Reverts the most recent action.");
row = view.addRow ();
view.set (row, 1, "task shell");
view.set (row, 2, "Launches an interactive shell.");
row = view.addRow ();
view.set (row, 1, "task duplicate ID [tags] [attrs] [desc...]");
view.set (row, 2, "Duplicates the specified task, and allows modifications.");
row = view.addRow ();
view.set (row, 1, "task delete ID");
view.set (row, 2, "Deletes the specified task.");
row = view.addRow ();
view.set (row, 1, "task info ID");
view.set (row, 2, "Shows all data, metadata for specified task.");
row = view.addRow ();
view.set (row, 1, "task start ID");
view.set (row, 2, "Marks specified task as started.");
row = view.addRow ();
view.set (row, 1, "task stop ID");
view.set (row, 2, "Removes the 'start' time from a task.");
row = view.addRow ();
view.set (row, 1, "task done ID [tags] [attrs] [desc...]");
view.set (row, 2, "Marks the specified task as completed.");
row = view.addRow ();
view.set (row, 1, "task projects");
view.set (row, 2, "Shows a list of all project names used, and how many tasks are in each.");
row = view.addRow ();
view.set (row, 1, "task tags");
view.set (row, 2, "Shows a list of all tags used.");
row = view.addRow ();
view.set (row, 1, "task summary");
view.set (row, 2, "Shows a report of task status by project.");
row = view.addRow ();
view.set (row, 1, "task timesheet [weeks]");
view.set (row, 2, "Shows a weekly report of tasks completed and started.");
row = view.addRow ();
view.set (row, 1, "task history");
view.set (row, 2, "Shows a report of task history, by month. Alias to history.monthly.");
row = view.addRow ();
view.set (row, 1, "task history.annual");
view.set (row, 2, "Shows a report of task history, by year.");
row = view.addRow ();
view.set (row, 1, "task ghistory");
view.set (row, 2, "Shows a graphical report of task history, by month. Alias to ghistory.monthly.");
row = view.addRow ();
view.set (row, 1, "task ghistory.annual");
view.set (row, 2, "Shows a graphical report of task history, by year.");
row = view.addRow ();
view.set (row, 1, "task burndown.daily");
view.set (row, 2, "Shows a graphical burndown chart, by day.");
row = view.addRow ();
view.set (row, 1, "task burndown.weekly");
view.set (row, 2, "Shows a graphical burndown chart, by week.");
row = view.addRow ();
view.set (row, 1, "task burndown.monthly");
view.set (row, 2, "Shows a graphical burndown chart, by month.");
row = view.addRow ();
view.set (row, 1, "task calendar [due|month year|year]");
view.set (row, 2, "Shows a calendar, with due tasks marked.");
row = view.addRow ();
view.set (row, 1, "task stats");
view.set (row, 2, "Shows task database statistics.");
row = view.addRow ();
view.set (row, 1, "task import");
view.set (row, 2, "Imports tasks from a variety of formats.");
row = view.addRow ();
view.set (row, 1, "task export");
view.set (row, 2, "Lists all tasks in CSV format. Alias to export.csv");
row = view.addRow ();
view.set (row, 1, "task export.csv");
view.set (row, 2, "Lists all tasks in CSV format.");
row = view.addRow ();
view.set (row, 1, "task export.ical");
view.set (row, 2, "Lists all tasks in iCalendar format.");
row = view.addRow ();
view.set (row, 1, "task export.yaml");
view.set (row, 2, "Lists all tasks in YAML format.");
row = view.addRow ();
view.set (row, 1, "task merge URL");
view.set (row, 2, "Merges the specified undo.data file with the local data files.");
row = view.addRow ();
view.set (row, 1, "task push URL");
view.set (row, 2, "Pushes the local *.data files to the URL.");
row = view.addRow ();
view.set (row, 1, "task pull URL");
view.set (row, 2, "Overwrites the local *.data files with those found at the URL.");
row = view.addRow ();
view.set (row, 1, "task color [sample | legend]");
view.set (row, 2, "Displays all possible colors, a named sample, or a "
"legend containing all currently defined colors.");
row = view.addRow ();
view.set (row, 1, "task count [filter]");
view.set (row, 2, "Shows only the number of matching tasks.");
row = view.addRow ();
view.set (row, 1, "task ids [filter]");
view.set (row, 2, "Shows only the IDs of matching tasks, in the form of a range.");
row = view.addRow ();
view.set (row, 1, "task version");
view.set (row, 2, "Shows the task version number.");
row = view.addRow ();
view.set (row, 1, "task show [all | substring]");
view.set (row, 2, "Shows the entire task configuration variables or the ones containing substring.");
row = view.addRow ();
view.set (row, 1, "task config [name [value | '']]");
view.set (row, 2, "Add, modify and remove settings in the task configuration.");
row = view.addRow ();
view.set (row, 1, "task diagnostics");
view.set (row, 2, "Information needed when reporting a problem.");
row = view.addRow ();
view.set (row, 1, "task help");
view.set (row, 2, "Shows the long usage text.");
// Add custom reports here...
std::vector <std::string> all;
context.cmd.allCustomReports (all);
foreach (report, all)
{
std::string command = std::string ("task ") + *report + std::string (" [tags] [attrs] desc...");
std::string description = context.config.get (std::string ("report.") + *report + ".description");
if (description == "")
description = "(missing description)";
row = view.addRow ();
view.set (row, 1, command);
view.set (row, 2, description);
}
std::stringstream out;
out << "\n"
<< view.render ()
<< "\n"
<< "Documentation for taskwarrior can be found using 'man task', "
<< "'man taskrc', 'man task-tutorial', 'man task-color', 'man task-faq' "
<< "or at http://taskwarrior.org"
<< "\n"
<< "\n";
outs = out.str ();
return 0;
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Display all information for the given task. // Display all information for the given task.
int handleInfo (std::string& outs) int handleInfo (std::string& outs)
@ -1408,7 +1174,7 @@ int handleReportCalendar (std::string& outs)
context.sequence.clear (); context.sequence.clear ();
std::string output; std::string output;
handleCustomReport (report, output); context.commands[report]->execute (context.commandLine, output);
out << output; out << output;
} }

View file

@ -265,7 +265,7 @@ int longestWord (const std::string& input)
std::string::size_type i = 0; std::string::size_type i = 0;
int character; int character;
while (character = utf8_next_char (input, i)) while ((character = utf8_next_char (input, i)))
{ {
if (character == ' ') if (character == ' ')
{ {

View file

@ -345,7 +345,7 @@ std::string compressIds (const std::vector <int>& ids)
int range_start = 0; int range_start = 0;
int range_end = 0; int range_end = 0;
for (int i = 0; i < ids.size (); ++i) for (unsigned int i = 0; i < ids.size (); ++i)
{ {
if (i + 1 == ids.size ()) if (i + 1 == ids.size ())
{ {