diff --git a/src/Context.cpp b/src/Context.cpp index 20fff5ac3..1383d6eac 100644 --- a/src/Context.cpp +++ b/src/Context.cpp @@ -45,19 +45,22 @@ //////////////////////////////////////////////////////////////////////////////// Context::Context () -: config () +: program ("") +, rc_file () +, data_dir () +, config () , filter () , sequence () , subst () , task () , tdb () , tdb2 () -, program ("") , commandLine ("") , file_override ("") , var_overrides ("") , cmd () , dom () +, determine_color_use (true) , use_color (true) , verbosity_legacy (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. - 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]); - } + // char** argv --> std::vector Context::args. + captureCommandLineArgs (argc, argv); - // 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; + // echo one two -- three | task zero --> task zero one two + // 'three' is left in the input buffer. + appendPipedArgs (); - args.push_back (arg); - } - } + // Assume default .taskrc and .task locations. + assumeLocations (); - // TODO Scan for rc: overrides --> apply. + // Process 'rc:' command line override, and remove the argument from the + // Context::args. + overrideRCFile (); - // Load the configuration file from the home directory. If the file cannot - // be found, offer to create a sample one. - loadCorrectConfigFile (); + // Dump any existing values and load rc file. + config.clear (); + 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 (); resolveAliases (); // Combine command line into one string. join (commandLine, " ", args); - // When redirecting output to a file, do not use color. - if (!isatty (fileno (stdout))) - { - config.set ("detection", "off"); - - if (! config.getBoolean ("_forcecolor")) - config.set ("color", "off"); - } - - if (config.getBoolean ("color")) + // Initialize the color rules, if necessary. + if (color ()) initializeColorRules (); - // Instantiate built-in command objects. Command::factory (commands); @@ -142,42 +126,6 @@ void Context::initialize2 (int argc, char** argv) // TODO Instantiate default command object. // TODO Instantiate extension UDA 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.), then strip it. std::string locale = config.get ("locale"); @@ -185,12 +133,14 @@ void Context::initialize () if (period != std::string::npos) locale = locale.substr (0, period); - // init TDB. + // Initialize the database. tdb.clear (); - std::vector all; - split (all, location, ','); - foreach (path, all) - tdb.location (*path); + tdb.location (data_dir); + + // Hook system init, plus post-start event occurring at the first possible + // moment after hook initialization. + hooks.initialize (); + hooks.trigger ("on-launch"); } //////////////////////////////////////////////////////////////////////////////// @@ -271,14 +221,22 @@ int Context::dispatch2 (std::string &out) std::vector matches; if (autoComplete (*arg, keywords, matches) == 1) { - Command* c = commands[matches[0]]; - if (! c->read_only ()) - tdb.gc (); + if (*arg != matches[0]) + debug ("Context::dispatch2 parse keyword '" + *arg + "' --> '" + matches[0] + "'"); + 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; } @@ -291,7 +249,6 @@ int Context::dispatch (std::string &out) // TODO Chain-of-command pattern dispatch. 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 == "config") { rc = handleConfig (out); } @@ -347,11 +304,10 @@ int Context::dispatch (std::string &out) sequence.size ()) { rc = handleModify (out); } // 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. - else { rc = shortUsage (out); } + else { rc = commands["help"]->execute (commandLine, out); } // Only update the shadow file if such an update was not suppressed (shadow), if ((cmd.isWriteCommand () || @@ -365,8 +321,35 @@ int Context::dispatch (std::string &out) //////////////////////////////////////////////////////////////////////////////// bool Context::color () { - return config.getBoolean ("color") || - config.getBoolean ("_forcecolor"); + if (determine_color_use) + { + // 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, ' '); - initialize (); + //initialize (); config.set ("detection", "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 options; - std::vector 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 ::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 { @@ -497,23 +450,24 @@ void Context::disallowModification () const // 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 // (foo, bar) as output. -void Context::applyOverrides ( - const std::vector & input, - std::vector & output) +void Context::applyOverrides () { + std::vector filtered; bool foundTerminator = false; - foreach (in, input) + + std::vector ::iterator arg; + for (arg = args.begin (); arg != args.end (); ++arg) { - if (*in == "--") + if (*arg == "--") { 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 value; - Nibbler n (*in); + Nibbler n (*arg); if (n.getLiteral ("rc.") && // rc. n.getUntilOneOf (":=", name) && // xxx n.skipN (1)) // : @@ -521,60 +475,114 @@ void Context::applyOverrides ( n.getUntilEOS (value); // Don't care if it's blank. config.set (name, value); - var_overrides += " " + *in; - footnote ("Configuration override " + in->substr (3)); + footnote ("Configuration override " + arg->substr (3)); + + // Overrides are retained for potential use by the default command. + var_overrides += " " + *arg; } else - footnote ("Problem with override: " + *in); + footnote ("Problem with override: " + *arg); } 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. struct passwd* pw = getpwuid (getuid ()); if (!pw) throw std::string ("Could not read home directory from the passwd file."); - std::string home = pw->pw_dir; - File rc (home + "/.taskrc"); - Directory data (home + "./task"); + home_dir = pw->pw_dir; + rc_file = File (home_dir + "/.taskrc"); + 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:? + std::vector ::iterator arg; + for (arg = args.begin (); arg != args.end (); ++arg) { + // Nothing after -- is to be interpreted in any way. if (*arg == "--") break; + else if (arg->substr (0, 3) == "rc:") { file_override = *arg; - rc = File (arg->substr (3)); + rc_file = File (arg->substr (3)); - home = rc; - std::string::size_type last_slash = rc.data.rfind ("/"); + home_dir = rc_file; + std::string::size_type last_slash = rc_file.data.rfind ("/"); if (last_slash != std::string::npos) - home = rc.data.substr (0, last_slash); + home_dir = rc_file.data.substr (0, last_slash); else - home = "."; + home_dir = "."; args.erase (arg); - header ("Using alternate .taskrc file " + rc.data); // TODO i18n - break; + header ("Using alternate .taskrc file " + rc_file.data); // TODO i18n + break; // Must break - iterator is dead. } } +} - // Load rc file. - config.clear (); // Dump current values. - config.load (rc); // Load new file. - +//////////////////////////////////////////////////////////////////////////////// +void Context::determineDataLocation () +{ 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) { if (*arg == "--") @@ -582,33 +590,32 @@ void Context::loadCorrectConfigFile () else if (arg->substr (0, 16) == "rc.data.location" && ((*arg)[16] == ':' || (*arg)[16] == '=')) { - data = Directory (arg->substr (17)); - header ("Using alternate data.location " + data.data); // TODO i18n + data_dir = Directory (arg->substr (17)); + header ("Using alternate data.location " + data_dir.data); // TODO i18n break; } } +} +//////////////////////////////////////////////////////////////////////////////// +void Context::createDefaultConfig () +{ // 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 - + home + + home_dir + "\n\n" + "Would you like a sample " - + rc.data + + rc_file.data + " created, so taskwarrior can proceed?")) throw std::string ("Cannot proceed without rc file."); - config.createDefaultRC (rc, data); + config.createDefaultRC (rc_file, data_dir); } // Create data location, if necessary. - config.createDefaultData (data); - - // Apply rc overrides. - std::vector filtered; - applyOverrides (args, filtered); - args = filtered; + config.createDefaultData (data_dir); } //////////////////////////////////////////////////////////////////////////////// @@ -892,7 +899,7 @@ void Context::parse ( file_override = ""; var_overrides = ""; footnotes.clear (); - initialize (); + //initialize (); parse (args, cmd, task, sequence, subst, filter); } else diff --git a/src/Context.h b/src/Context.h index 3d817e9b3..db2a97f2e 100644 --- a/src/Context.h +++ b/src/Context.h @@ -49,10 +49,8 @@ public: Context (const Context&); Context& operator= (const Context&); - void initialize (int, char**); // all startup TODO Obsolete - void initialize2 (int, char**); // all startup - void initialize (); // for reinitializing - int run (); // task classic + void initialize (int, char**); // all startup + int run (); int dispatch2 (std::string&); // command handler dispatch int dispatch (std::string&); // command handler dispatch void shadow (); // shadow file update @@ -72,13 +70,17 @@ public: void parse (std::vector &, Cmd&, Task&, Sequence&, Subst&, Filter&); void clear (); - std::string canonicalize (const std::string&) const; void disallowModification () const; - void applyOverrides (const std::vector &, std::vector &); + void applyOverrides (); void decomposeSortField (const std::string&, std::string&, bool&); private: - void loadCorrectConfigFile (); + void captureCommandLineArgs (int, char**); + void appendPipedArgs (); + void assumeLocations (); + void overrideRCFile (); + void determineDataLocation (); + void createDefaultConfig (); void loadAliases (); void resolveAliases (); void autoFilter (Att&, Filter&); @@ -86,15 +88,19 @@ private: void updateXtermTitle (); public: + std::string program; + std::vector args; + std::string home_dir; + File rc_file; + Path data_dir; Config config; + Filter filter; Sequence sequence; Subst subst; Task task; TDB tdb; // TODO Obsolete TDB2 tdb2; - std::string program; - std::vector args; std::string commandLine; std::string file_override; std::string var_overrides; @@ -104,6 +110,9 @@ public: std::vector tagRemovals; Hooks hooks; DOM dom; + + // Color + bool determine_color_use; bool use_color; bool verbosity_legacy; diff --git a/src/JSON.cpp b/src/JSON.cpp index db8f5dd99..91a70ab8e 100644 --- a/src/JSON.cpp +++ b/src/JSON.cpp @@ -182,7 +182,7 @@ json::array* json::array::parse (Nibbler& nibbler) json::array* arr = new json::array (); json::value* value; - if (value = json::value::parse (n)) + if ((value = json::value::parse (n))) { arr->push_back (value); value = NULL; // Not a leak. Looks like a leak. @@ -191,7 +191,7 @@ json::array* json::array::parse (Nibbler& nibbler) { n.skipWS (); - if (value = json::value::parse (n)) + if ((value = json::value::parse (n))) { arr->push_back (value); n.skipWS (); @@ -323,7 +323,7 @@ bool json::object::parse_pair ( if (n.skip (':')) { n.skipWS (); - if (val = json::value::parse (n)) + if ((val = json::value::parse (n))) { nibbler = n; return true; diff --git a/src/Variant.cpp b/src/Variant.cpp index d4d448ace..e6b0ee629 100644 --- a/src/Variant.cpp +++ b/src/Variant.cpp @@ -45,29 +45,12 @@ Variant::Variant (const Variant& other) // Explicitly copy only the relevant type. This saves memory. switch (mType) { - case v_boolean: - mBool = other.mBool; - break; - - case v_integer: - mInteger = other.mInteger; - 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; + case v_boolean: mBool = other.mBool; break; + case v_integer: mInteger = other.mInteger; 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) { case v_boolean: - throw std::string ("Cannot perform relationally compare Boolean types"); + throw std::string ("Cannot perform relational compare Boolean types"); break; case v_integer: @@ -501,7 +484,7 @@ Variant& Variant::operator> (const Variant& other) switch (mType) { case v_boolean: - throw std::string ("Cannot perform relationally compare Boolean types"); + throw std::string ("Cannot perform relational compare Boolean types"); break; case v_integer: diff --git a/src/command.cpp b/src/command.cpp index 85700dc4a..b015fd0da 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -331,78 +331,6 @@ int handleCompletionProjects (std::string& outs) return 0; } -//////////////////////////////////////////////////////////////////////////////// -int handleTags (std::string& outs) -{ - int rc = 0; - std::stringstream out; - - std::vector 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 unique; - foreach (t, tasks) - { - std::vector 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) { @@ -2302,8 +2230,7 @@ void handleShell () split (args, decoratedCommand, ' '); foreach (arg, args) context.args.push_back (*arg); - context.initialize2 (0, NULL); - context.initialize (); + context.initialize (0, NULL); context.run (); } diff --git a/src/main.cpp b/src/main.cpp index 41c315445..d4db3f5dd 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -63,7 +63,6 @@ int main (int argc, char** argv) try { - context.initialize2 (argc, argv); context.initialize (argc, argv); status = context.run (); } diff --git a/src/main.h b/src/main.h index a77d5b04e..15b00157f 100644 --- a/src/main.h +++ b/src/main.h @@ -57,7 +57,6 @@ 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&); @@ -98,7 +97,6 @@ void handleDiagnostics (std::string&); int handleEdit (std::string&); // report.cpp -int shortUsage (std::string&); int handleInfo (std::string&); int handleReportSummary (std::string&); int handleReportCalendar (std::string&); @@ -120,12 +118,6 @@ int handleReportHistoryAnnual (std::string&); int handleReportGHistoryMonthly (std::string&); int handleReportGHistoryAnnual (std::string&); -// custom.cpp -int handleCustomReport (const std::string&, std::string&); -void validateReportColumns (const std::vector &); -void validateSortColumns (const std::vector &); -void getLimits (const std::string&, int&, int&); - // rules.cpp void initializeColorRules (); void autoColorize (Task&, Color&); diff --git a/src/report.cpp b/src/report.cpp index 5f76dea36..87d2506cf 100644 --- a/src/report.cpp +++ b/src/report.cpp @@ -51,240 +51,6 @@ static void countTasks (const std::vector &, const std::string&, const std 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 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. int handleInfo (std::string& outs) @@ -1408,7 +1174,7 @@ int handleReportCalendar (std::string& outs) context.sequence.clear (); std::string output; - handleCustomReport (report, output); + context.commands[report]->execute (context.commandLine, output); out << output; } diff --git a/src/text.cpp b/src/text.cpp index c491badb7..fa329a8db 100644 --- a/src/text.cpp +++ b/src/text.cpp @@ -265,7 +265,7 @@ int longestWord (const std::string& input) std::string::size_type i = 0; int character; - while (character = utf8_next_char (input, i)) + while ((character = utf8_next_char (input, i))) { if (character == ' ') { diff --git a/src/util.cpp b/src/util.cpp index 30e879eeb..d15149338 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -345,7 +345,7 @@ std::string compressIds (const std::vector & ids) int range_start = 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 ()) {