diff --git a/.github/workflows/release-check.yaml b/.github/workflows/release-check.yaml index e9cf424ba..7ec39eb1d 100644 --- a/.github/workflows/release-check.yaml +++ b/.github/workflows/release-check.yaml @@ -25,4 +25,3 @@ jobs: cd task-*.*.* && cmake -S. -Bbuild && cmake --build build --target task_executable - diff --git a/ChangeLog b/ChangeLog index 3f7d99266..6a8b78bb5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -44,7 +44,7 @@ - Akash Shanmugaraj - Andrew Savchenko - - Dathan Bennett + - Dathan Bennett - Dustin Mitchell - dbr/Ben - Felix Schurk @@ -2785,4 +2785,3 @@ regular usage to determine which features were needed or unnecessary.] - Usage. ------ start ----------------------------------- - diff --git a/LICENSE b/LICENSE index 89dcf89c2..96d1910f0 100644 --- a/LICENSE +++ b/LICENSE @@ -21,4 +21,3 @@ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - diff --git a/cmake.h.in b/cmake.h.in index 6586a7f03..ec294bf99 100644 --- a/cmake.h.in +++ b/cmake.h.in @@ -58,4 +58,3 @@ /* Undefine this to eliminate the execute command */ #define HAVE_EXECUTE 1 - diff --git a/doc/devel/rfcs/dom.md b/doc/devel/rfcs/dom.md index ccc00515b..2a9a76586 100644 --- a/doc/devel/rfcs/dom.md +++ b/doc/devel/rfcs/dom.md @@ -227,14 +227,14 @@ An example is to make two reports share the same description: $ task config -- report.ls.description rc.report.list.description -This sets the description for the `ls` report to be a reference to the description of the `list` report. +This sets the description for the `ls` report to be a reference to the description of the `list` report. This reference is not evaluated when the entry is written, but is evaluated every time the value is read, thus providing late-bound behavior. Then if the description of the `list` report changes, so does that of the `ls` report automatically. ## Implementation Details -These notes list a series of anticipated changes to the codebase. +These notes list a series of anticipated changes to the codebase. - The `src/columns/Col*` objects will implement type-specific and attribute-specific DOM support. DOM reference lookup will defer to the column objects first. diff --git a/doc/devel/rfcs/task.md b/doc/devel/rfcs/task.md index a1ab4927f..312b8ee72 100644 --- a/doc/devel/rfcs/task.md +++ b/doc/devel/rfcs/task.md @@ -466,4 +466,3 @@ Given that the configuration is not present in the JSON format of a task, any fi This means that if a task contains a UDA, unless the meaning of it is understood, it MUST be preserved. UDAs may have one of four types: string, numeric, date and duration. - diff --git a/doc/man/task-sync.5.in b/doc/man/task-sync.5.in index 9e1cdb320..18f8a8189 100644 --- a/doc/man/task-sync.5.in +++ b/doc/man/task-sync.5.in @@ -101,7 +101,7 @@ Then configure Taskwarrior with: $ task config sync.gcp.bucket .fi -However you can bring your own service account credentials if your +However you can bring your own service account credentials if your `application-default` is already being used by some other application To begin, navigate to the "IAM and Admin" section in the Navigation Menu, then select "Roles." @@ -112,8 +112,8 @@ Provide an appropriate name and description for the new role. Add permissions to your new role using the filter "Service:storage" (not the "Filter permissions by role" input box). Select the following permissions: - - storage.buckets.create - - storage.buckets.get + - storage.buckets.create + - storage.buckets.get - storage.buckets.update - storage.objects.create - storage.objects.delete diff --git a/doc/rc/bubblegum-256.theme b/doc/rc/bubblegum-256.theme index 2bb005611..ac7b87e73 100644 --- a/doc/rc/bubblegum-256.theme +++ b/doc/rc/bubblegum-256.theme @@ -96,4 +96,3 @@ color.sync.rejected=rgb103 # Command: undo color.undo.before=rgb103 color.undo.after=rgb305 - diff --git a/doc/rc/dark-16.theme b/doc/rc/dark-16.theme index 6ac6505d7..c7778848e 100644 --- a/doc/rc/dark-16.theme +++ b/doc/rc/dark-16.theme @@ -98,4 +98,3 @@ color.sync.rejected=red # Command: undo color.undo.after=green color.undo.before=red - diff --git a/doc/rc/dark-256.theme b/doc/rc/dark-256.theme index 4398fa96a..17fcb8fe6 100644 --- a/doc/rc/dark-256.theme +++ b/doc/rc/dark-256.theme @@ -95,4 +95,3 @@ color.sync.rejected=color9 # Command: undo color.undo.after=color2 color.undo.before=color1 - diff --git a/doc/rc/dark-blue-256.theme b/doc/rc/dark-blue-256.theme index 91b1c6ca4..ec974ce7e 100644 --- a/doc/rc/dark-blue-256.theme +++ b/doc/rc/dark-blue-256.theme @@ -95,4 +95,3 @@ color.sync.rejected=rgb004 # Command: undo color.undo.after=rgb035 color.undo.before=rgb013 - diff --git a/doc/rc/dark-gray-256.theme b/doc/rc/dark-gray-256.theme index f169abaa4..b6fdb343e 100644 --- a/doc/rc/dark-gray-256.theme +++ b/doc/rc/dark-gray-256.theme @@ -95,4 +95,3 @@ color.sync.rejected=gray5 on gray23 # Command: undo color.undo.before=white on black color.undo.after=black on white - diff --git a/doc/rc/dark-gray-blue-256.theme b/doc/rc/dark-gray-blue-256.theme index 97bb242b4..8b65e615d 100644 --- a/doc/rc/dark-gray-blue-256.theme +++ b/doc/rc/dark-gray-blue-256.theme @@ -95,4 +95,3 @@ color.sync.rejected=gray23 # Command: undo color.undo.before=rgb013 color.undo.after=rgb035 - diff --git a/doc/rc/dark-red-256.theme b/doc/rc/dark-red-256.theme index 414e1077f..8c655d2ae 100644 --- a/doc/rc/dark-red-256.theme +++ b/doc/rc/dark-red-256.theme @@ -95,4 +95,3 @@ color.sync.rejected=rgb200 # Command: undo color.undo.after=rgb511 color.undo.before=rgb200 - diff --git a/doc/rc/dark-violets-256.theme b/doc/rc/dark-violets-256.theme index 0cd56e6df..395777cc6 100644 --- a/doc/rc/dark-violets-256.theme +++ b/doc/rc/dark-violets-256.theme @@ -95,4 +95,3 @@ color.sync.rejected=rgb103 # Command: undo color.undo.before=rgb103 color.undo.after=rgb305 - diff --git a/doc/rc/dark-yellow-green.theme b/doc/rc/dark-yellow-green.theme index da7429a46..4a9dcbc00 100644 --- a/doc/rc/dark-yellow-green.theme +++ b/doc/rc/dark-yellow-green.theme @@ -95,4 +95,3 @@ color.sync.rejected=rgb110 # Command: undo color.undo.before=rgb021 color.undo.after=rgb042 - diff --git a/doc/rc/light-16.theme b/doc/rc/light-16.theme index 885c7367d..c310dd301 100644 --- a/doc/rc/light-16.theme +++ b/doc/rc/light-16.theme @@ -95,4 +95,3 @@ color.sync.rejected=red # Command: undo color.undo.before=yellow color.undo.after=green - diff --git a/doc/rc/light-256.theme b/doc/rc/light-256.theme index e8eb896f3..8044efbb0 100644 --- a/doc/rc/light-256.theme +++ b/doc/rc/light-256.theme @@ -65,7 +65,7 @@ color.due.today=on rgb353 color.overdue=on rgb544 # Report: burndown -color.burndown.pending=on rgb411 +color.burndown.pending=on rgb411 color.burndown.started=on rgb550 color.burndown.done=on rgb151 @@ -95,4 +95,3 @@ color.sync.rejected=red # Command: undo color.undo.before=yellow color.undo.after=green - diff --git a/doc/rc/no-color.theme b/doc/rc/no-color.theme index af085c04d..ae387e5ba 100644 --- a/doc/rc/no-color.theme +++ b/doc/rc/no-color.theme @@ -98,4 +98,3 @@ color.sync.rejected= # Command: undo color.undo.after= color.undo.before= - diff --git a/doc/rc/refresh b/doc/rc/refresh index 361dc85fa..78ce19f45 100755 --- a/doc/rc/refresh +++ b/doc/rc/refresh @@ -6,4 +6,3 @@ do echo $locale ../../scripts/add-ons/update-holidays.pl --locale $locale --file holidays.${locale}.rc done - diff --git a/doc/rc/solarized-dark-256.theme b/doc/rc/solarized-dark-256.theme index b8551d971..cd61504c3 100644 --- a/doc/rc/solarized-dark-256.theme +++ b/doc/rc/solarized-dark-256.theme @@ -112,4 +112,3 @@ color.sync.rejected=color13 # Command: undo color.undo.after=color2 color.undo.before=color1 - diff --git a/doc/rc/solarized-light-256.theme b/doc/rc/solarized-light-256.theme index 55c524e01..9cdd56453 100644 --- a/doc/rc/solarized-light-256.theme +++ b/doc/rc/solarized-light-256.theme @@ -112,4 +112,3 @@ color.sync.rejected=color13 # Command: undo color.undo.after=color2 color.undo.before=color1 - diff --git a/misc/themes/README b/misc/themes/README index 37a373e58..6417a68c3 100644 --- a/misc/themes/README +++ b/misc/themes/README @@ -25,4 +25,3 @@ Using a solarized light terminal, run the following: Note that for the solarized themes, the terminal color palette needs to be set to specific colors. - diff --git a/misc/themes/setup b/misc/themes/setup index 869ba67dc..e2882e8b1 100755 --- a/misc/themes/setup +++ b/misc/themes/setup @@ -30,4 +30,3 @@ task rc:x add Deleted_1 task rc:x 14 mod depends:13 task rc:x 15 delete - diff --git a/performance/CMakeLists.txt b/performance/CMakeLists.txt index 293c5b942..a8fff9921 100644 --- a/performance/CMakeLists.txt +++ b/performance/CMakeLists.txt @@ -7,5 +7,3 @@ configure_file(run_perf run_perf) add_custom_target (performance ${CMAKE_BINARY_DIR}/performance/run_perf DEPENDS task_executable WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/performance) - - diff --git a/performance/compare_runs.py b/performance/compare_runs.py index 834332a18..c4b86ea7c 100755 --- a/performance/compare_runs.py +++ b/performance/compare_runs.py @@ -29,10 +29,13 @@ def parse_perf(input): tests[command] = [] # Parse concatenated run_perf output - for i in re.findall("^ - task %s\\.\\.\\.\n" - "Perf task ([^ ]+) ([^ ]+) ([^ ]+) (.+)$" - % command, input, re.MULTILINE): - info = i[0:3] + ({k:v for k, v in (i.split(":") for i in i[-1].split())},) + for i in re.findall( + "^ - task %s\\.\\.\\.\n" + "Perf task ([^ ]+) ([^ ]+) ([^ ]+) (.+)$" % command, + input, + re.MULTILINE, + ): + info = i[0:3] + ({k: v for k, v in (i.split(":") for i in i[-1].split())},) pt = TaskPerf(*info) tests[command].append(pt) return tests @@ -61,8 +64,14 @@ with open(sys.argv[2], "r") as fh: tests_cur = parse_perf(fh.read()) best_cur = get_best(tests_cur) -print("Previous: %s (%s)" % (tests_prev[COMMANDS[0]][0].version, tests_prev[COMMANDS[0]][0].commit)) -print("Current: %s (%s)" % (tests_cur[COMMANDS[0]][0].version, tests_cur[COMMANDS[0]][0].commit)) +print( + "Previous: %s (%s)" + % (tests_prev[COMMANDS[0]][0].version, tests_prev[COMMANDS[0]][0].commit) +) +print( + "Current: %s (%s)" + % (tests_cur[COMMANDS[0]][0].version, tests_cur[COMMANDS[0]][0].commit) +) for test in COMMANDS: print("# %s:" % test) @@ -76,7 +85,9 @@ for test in COMMANDS: else: percentage = "0%" - pad = max(map(len, (k, best_prev[test][k], best_cur[test][k], diff, percentage))) + pad = max( + map(len, (k, best_prev[test][k], best_cur[test][k], diff, percentage)) + ) out[0] += " %s" % k.rjust(pad) out[1] += " %s" % best_prev[test][k].rjust(pad) out[2] += " %s" % best_cur[test][k].rjust(pad) diff --git a/performance/run_perf b/performance/run_perf index 8d925efb9..829fe1723 100755 --- a/performance/run_perf +++ b/performance/run_perf @@ -50,4 +50,3 @@ $TASK rc.debug:1 rc:perf.rc import ${CMAKE_SOURCE_DIR}/performance/export.json 2 echo 'End' exit 0 - diff --git a/performance/sample-text.txt b/performance/sample-text.txt index 5b6e09ba9..acc17fb25 100644 --- a/performance/sample-text.txt +++ b/performance/sample-text.txt @@ -3963,7 +3963,7 @@ GLOUCESTER Give me the letter, sir. EDMUND I shall offend, either to detain or give it. The contents, as in part I understand them, are to blame. GLOUCESTER Lets see, lets see. EDMUND I hope, for my brothers justification, he wrote this but as an essay or taste of my virtue. -GLOUCESTER This policy and reverence of age makes the world bitter to the best of our times, keeps our fortunes from us till our oldness cannot relish them. I begin to find an idle and fond bondage in the oppression of aged tyranny, who sways, not as it hath power, but as it is suffered. Come to me, that of this I may speak more. If our father would sleep till I waked him, you should enjoy half his revenue for ever, and live the beloved of your brother, +GLOUCESTER This policy and reverence of age makes the world bitter to the best of our times, keeps our fortunes from us till our oldness cannot relish them. I begin to find an idle and fond bondage in the oppression of aged tyranny, who sways, not as it hath power, but as it is suffered. Come to me, that of this I may speak more. If our father would sleep till I waked him, you should enjoy half his revenue for ever, and live the beloved of your brother, EDMUND It was not brought me, my lord, theres the cunning of it, I found it thrown in at the casement of my closet. GLOUCESTER You know the character to be your brothers? EDMUND If the matter were good, my lord, I durst swear it were his, but, in respect of that, I would fain think it were not. diff --git a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt index c0f40fe3e..3d06cedaf 100644 --- a/scripts/CMakeLists.txt +++ b/scripts/CMakeLists.txt @@ -8,4 +8,3 @@ install (DIRECTORY add-ons FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) - diff --git a/scripts/add-ons/update-holidays.pl b/scripts/add-ons/update-holidays.pl index 7849cbe69..e3360040e 100755 --- a/scripts/add-ons/update-holidays.pl +++ b/scripts/add-ons/update-holidays.pl @@ -221,4 +221,3 @@ if (open my $fh, '>:utf8', $file) exit 0; ################################################################################ - diff --git a/scripts/hooks/README b/scripts/hooks/README index ecfea194e..ecb36e579 100644 --- a/scripts/hooks/README +++ b/scripts/hooks/README @@ -24,4 +24,3 @@ Expected Permissions Interface Each hook script has a unique interface. This is documented in the example scripts here. - diff --git a/scripts/hooks/on-exit.shadow-file b/scripts/hooks/on-exit.shadow-file index 3434c83f5..bf8d94d5d 100755 --- a/scripts/hooks/on-exit.shadow-file +++ b/scripts/hooks/on-exit.shadow-file @@ -32,4 +32,3 @@ fi echo Shadow file $SHADOW_FILE updated. exit 0 - diff --git a/scripts/hooks/on-launch b/scripts/hooks/on-launch index 6f8739374..3a1bcc9fb 100755 --- a/scripts/hooks/on-launch +++ b/scripts/hooks/on-launch @@ -14,4 +14,3 @@ echo 'on-launch' # - 0: JSON ignored, non-JSON is feedback. # - non-0: JSON ignored, non-JSON is error. exit 0 - diff --git a/scripts/vim/ftdetect/task.vim b/scripts/vim/ftdetect/task.vim index ab3acd9c6..952c825d8 100644 --- a/scripts/vim/ftdetect/task.vim +++ b/scripts/vim/ftdetect/task.vim @@ -1,4 +1,4 @@ -" Vim support file to detect Taskwarrior data and configuration files and +" Vim support file to detect Taskwarrior data and configuration files and " single task edits " " Maintainer: John Florian diff --git a/scripts/zsh/_task b/scripts/zsh/_task index 45fb7fd87..013e2065d 100644 --- a/scripts/zsh/_task +++ b/scripts/zsh/_task @@ -289,4 +289,4 @@ _task_default() { } _arguments -s -S \ - "*::task default:_task_default" \ No newline at end of file + "*::task default:_task_default" diff --git a/src/CLI2.cpp b/src/CLI2.cpp index eca04fabe..f951b3c9e 100644 --- a/src/CLI2.cpp +++ b/src/CLI2.cpp @@ -28,18 +28,18 @@ // cmake.h include header must come first #include -#include -#include -#include -#include -#include -#include -#include -#include #include #include +#include +#include +#include +#include +#include +#include #include +#include +#include // Overridden by rc.abbreviation.minimum. int CLI2::minimumMatchLength = 3; @@ -48,298 +48,253 @@ int CLI2::minimumMatchLength = 3; static int safetyValveDefault = 10; //////////////////////////////////////////////////////////////////////////////// -A2::A2 (const std::string& raw, Lexer::Type lextype) -{ +A2::A2(const std::string& raw, Lexer::Type lextype) { _lextype = lextype; - attribute ("raw", raw); + attribute("raw", raw); } //////////////////////////////////////////////////////////////////////////////// -A2::A2 (const A2& other) = default; +A2::A2(const A2& other) = default; //////////////////////////////////////////////////////////////////////////////// -A2& A2::operator= (const A2& other) = default; +A2& A2::operator=(const A2& other) = default; //////////////////////////////////////////////////////////////////////////////// -bool A2::hasTag (const std::string& tag) const -{ - return std::find (_tags.begin (), _tags.end (), tag) != _tags.end (); +bool A2::hasTag(const std::string& tag) const { + return std::find(_tags.begin(), _tags.end(), tag) != _tags.end(); } //////////////////////////////////////////////////////////////////////////////// -void A2::tag (const std::string& tag) -{ - if (! hasTag (tag)) - _tags.push_back (tag); +void A2::tag(const std::string& tag) { + if (!hasTag(tag)) _tags.push_back(tag); } //////////////////////////////////////////////////////////////////////////////// -void A2::unTag (const std::string& tag) -{ - for (auto i = _tags.begin (); i != _tags.end (); ++i) - if (*i == tag) - { - _tags.erase (i); +void A2::unTag(const std::string& tag) { + for (auto i = _tags.begin(); i != _tags.end(); ++i) + if (*i == tag) { + _tags.erase(i); break; } } //////////////////////////////////////////////////////////////////////////////// // Accessor for attributes. -void A2::attribute (const std::string& name, const std::string& value) -{ +void A2::attribute(const std::string& name, const std::string& value) { _attributes[name] = value; - if (name == "raw") - decompose (); + if (name == "raw") decompose(); } //////////////////////////////////////////////////////////////////////////////// // Accessor for attributes. -const std::string A2::attribute (const std::string& name) const -{ +const std::string A2::attribute(const std::string& name) const { // Prevent autovivification. - auto i = _attributes.find (name); - if (i != _attributes.end ()) - return i->second; + auto i = _attributes.find(name); + if (i != _attributes.end()) return i->second; return ""; } //////////////////////////////////////////////////////////////////////////////// -const std::string A2::getToken () const -{ - auto i = _attributes.find ("canonical"); - if (i == _attributes.end ()) - i = _attributes.find ("raw"); +const std::string A2::getToken() const { + auto i = _attributes.find("canonical"); + if (i == _attributes.end()) i = _attributes.find("raw"); return i->second; } //////////////////////////////////////////////////////////////////////////////// -void A2::decompose () -{ - if (_lextype == Lexer::Type::tag) - { +void A2::decompose() { + if (_lextype == Lexer::Type::tag) { std::string raw = _attributes["raw"]; - attribute ("name", raw.substr (1)); - attribute ("sign", raw.substr (0, 1)); + attribute("name", raw.substr(1)); + attribute("sign", raw.substr(0, 1)); } - else if (_lextype == Lexer::Type::substitution) - { - //if (Directory (raw).exists ()) - // return; + else if (_lextype == Lexer::Type::substitution) { + // if (Directory (raw).exists ()) + // return; std::string from; std::string to; std::string flags; - if (Lexer::decomposeSubstitution (_attributes["raw"], from, to, flags)) - { - attribute ("from", from); - attribute ("to", to); - attribute ("flags", flags); + if (Lexer::decomposeSubstitution(_attributes["raw"], from, to, flags)) { + attribute("from", from); + attribute("to", to); + attribute("flags", flags); } } - else if (_lextype == Lexer::Type::pair) - { + else if (_lextype == Lexer::Type::pair) { std::string name; std::string mod; std::string sep; std::string value; - if (Lexer::decomposePair (_attributes["raw"], name, mod, sep, value)) - { - attribute ("name", name); - attribute ("modifier", mod); - attribute ("separator", sep); - attribute ("value", value); + if (Lexer::decomposePair(_attributes["raw"], name, mod, sep, value)) { + attribute("name", name); + attribute("modifier", mod); + attribute("separator", sep); + attribute("value", value); - if (name == "rc") - { + if (name == "rc") { if (mod != "") - tag ("CONFIG"); + tag("CONFIG"); else - tag ("RC"); + tag("RC"); } } } - else if (_lextype == Lexer::Type::pattern) - { - //if (Directory (raw).exists ()) - // return; + else if (_lextype == Lexer::Type::pattern) { + // if (Directory (raw).exists ()) + // return; std::string pattern; std::string flags; - if (Lexer::decomposePattern (_attributes["raw"], pattern, flags)) - { - attribute ("pattern", pattern); - attribute ("flags", flags); + if (Lexer::decomposePattern(_attributes["raw"], pattern, flags)) { + attribute("pattern", pattern); + attribute("flags", flags); } } } //////////////////////////////////////////////////////////////////////////////// -const std::string A2::dump () const -{ - auto output = Lexer::typeToString (_lextype); +const std::string A2::dump() const { + auto output = Lexer::typeToString(_lextype); // Dump attributes. std::string atts; - for (const auto& a : _attributes) - atts += a.first + "='\033[33m" + a.second + "\033[0m' "; + for (const auto& a : _attributes) atts += a.first + "='\033[33m" + a.second + "\033[0m' "; // Dump tags. std::string tags; - for (const auto& tag : _tags) - { - if (tag == "BINARY") tags += "\033[1;37;44m" + tag + "\033[0m "; - else if (tag == "CMD") tags += "\033[1;37;46m" + tag + "\033[0m "; - else if (tag == "FILTER") tags += "\033[1;37;42m" + tag + "\033[0m "; - else if (tag == "MODIFICATION") tags += "\033[1;37;43m" + tag + "\033[0m "; - else if (tag == "MISCELLANEOUS") tags += "\033[1;37;45m" + tag + "\033[0m "; - else if (tag == "RC") tags += "\033[1;37;41m" + tag + "\033[0m "; - else if (tag == "CONFIG") tags += "\033[1;37;101m" + tag + "\033[0m "; - else if (tag == "?") tags += "\033[38;5;255;48;5;232m" + tag + "\033[0m "; - else tags += "\033[32m" + tag + "\033[0m "; + for (const auto& tag : _tags) { + if (tag == "BINARY") + tags += "\033[1;37;44m" + tag + "\033[0m "; + else if (tag == "CMD") + tags += "\033[1;37;46m" + tag + "\033[0m "; + else if (tag == "FILTER") + tags += "\033[1;37;42m" + tag + "\033[0m "; + else if (tag == "MODIFICATION") + tags += "\033[1;37;43m" + tag + "\033[0m "; + else if (tag == "MISCELLANEOUS") + tags += "\033[1;37;45m" + tag + "\033[0m "; + else if (tag == "RC") + tags += "\033[1;37;41m" + tag + "\033[0m "; + else if (tag == "CONFIG") + tags += "\033[1;37;101m" + tag + "\033[0m "; + else if (tag == "?") + tags += "\033[38;5;255;48;5;232m" + tag + "\033[0m "; + else + tags += "\033[32m" + tag + "\033[0m "; } return output + ' ' + atts + tags; } //////////////////////////////////////////////////////////////////////////////// -static -const char* getValue (int argc, const char** argv, std::string arg) -{ - const auto is_arg = [&] (std::string s) - { - return s.size () > arg.size () + 1 - && (s[arg.size ()] == ':' || s[arg.size ()] == '=') - && s.compare (0, arg.size (), arg) == 0; +static const char* getValue(int argc, const char** argv, std::string arg) { + const auto is_arg = [&](std::string s) { + return s.size() > arg.size() + 1 && (s[arg.size()] == ':' || s[arg.size()] == '=') && + s.compare(0, arg.size(), arg) == 0; }; // find last argument before -- - auto last = std::make_reverse_iterator (argv); - auto first = std::make_reverse_iterator ( - std::find (argv, argv + argc, std::string ("--"))); - auto it = std::find_if (first, last, is_arg); - if (it == last) - return nullptr; + auto last = std::make_reverse_iterator(argv); + auto first = std::make_reverse_iterator(std::find(argv, argv + argc, std::string("--"))); + auto it = std::find_if(first, last, is_arg); + if (it == last) return nullptr; // return the string after : or = - return *it + arg.size () + 1; + return *it + arg.size() + 1; } //////////////////////////////////////////////////////////////////////////////// // Static method. -bool CLI2::getOverride (int argc, const char** argv, File& rc) -{ - const char* value = getValue (argc, argv, "rc"); - if (value == nullptr) - return false; - rc = File (value); +bool CLI2::getOverride(int argc, const char** argv, File& rc) { + const char* value = getValue(argc, argv, "rc"); + if (value == nullptr) return false; + rc = File(value); return true; } //////////////////////////////////////////////////////////////////////////////// // Look for CONFIG data.location and initialize a Path object. // Static method. -bool CLI2::getDataLocation (int argc, const char** argv, Path& data) -{ - const char* value = getValue (argc, argv, "rc.data.location"); - if (value == nullptr) - { - std::string location = Context::getContext ().config.get ("data.location"); - if (location != "") - data = location; +bool CLI2::getDataLocation(int argc, const char** argv, Path& data) { + const char* value = getValue(argc, argv, "rc.data.location"); + if (value == nullptr) { + std::string location = Context::getContext().config.get("data.location"); + if (location != "") data = location; return false; } - data = Directory (value); + data = Directory(value); return true; } //////////////////////////////////////////////////////////////////////////////// // Static method. -void CLI2::applyOverrides (int argc, const char** argv) -{ - auto& context = Context::getContext (); - auto last = std::find (argv, argv + argc, std::string ("--")); - auto is_override = [] (const std::string& s) - { - return s.compare (0, 3, "rc.") == 0; - }; - auto get_sep = [&] (const std::string& s) - { - if (is_override (s)) - return s.find_first_of (":=", 3); +void CLI2::applyOverrides(int argc, const char** argv) { + auto& context = Context::getContext(); + auto last = std::find(argv, argv + argc, std::string("--")); + auto is_override = [](const std::string& s) { return s.compare(0, 3, "rc.") == 0; }; + auto get_sep = [&](const std::string& s) { + if (is_override(s)) return s.find_first_of(":=", 3); return std::string::npos; }; - auto override_settings = [&] (std::string raw) - { - auto sep = get_sep (raw); - if (sep == std::string::npos) - return; - std::string name = raw.substr (3, sep - 3); - std::string value = raw.substr (sep + 1); - context.config.set (name, value); + auto override_settings = [&](std::string raw) { + auto sep = get_sep(raw); + if (sep == std::string::npos) return; + std::string name = raw.substr(3, sep - 3); + std::string value = raw.substr(sep + 1); + context.config.set(name, value); }; - auto display_overrides = [&] (std::string raw) - { - if (is_override (raw)) - context.footnote (format ("Configuration override {1}", raw)); + auto display_overrides = [&](std::string raw) { + if (is_override(raw)) context.footnote(format("Configuration override {1}", raw)); }; - std::for_each (argv, last, override_settings); - if (context.verbose ("override")) - std::for_each (argv, last, display_overrides); + std::for_each(argv, last, override_settings); + if (context.verbose("override")) std::for_each(argv, last, display_overrides); } //////////////////////////////////////////////////////////////////////////////// -void CLI2::alias (const std::string& name, const std::string& value) -{ - _aliases[name] = value; -} +void CLI2::alias(const std::string& name, const std::string& value) { _aliases[name] = value; } //////////////////////////////////////////////////////////////////////////////// -void CLI2::entity (const std::string& category, const std::string& name) -{ +void CLI2::entity(const std::string& category, const std::string& name) { // Walk the list of entities for category. - auto c = _entities.equal_range (category); + auto c = _entities.equal_range(category); for (auto e = c.first; e != c.second; ++e) - if (e->second == name) - return; + if (e->second == name) return; // The category/name pair was not found, therefore add it. - _entities.emplace (category, name); + _entities.emplace(category, name); } //////////////////////////////////////////////////////////////////////////////// // Capture a single argument. -void CLI2::add (const std::string& argument) -{ - A2 arg (Lexer::trim (argument), Lexer::Type::word); - arg.tag ("ORIGINAL"); - _original_args.push_back (arg); +void CLI2::add(const std::string& argument) { + A2 arg(Lexer::trim(argument), Lexer::Type::word); + arg.tag("ORIGINAL"); + _original_args.push_back(arg); // Adding a new argument invalidates prior analysis. - _args.clear (); + _args.clear(); } //////////////////////////////////////////////////////////////////////////////// // Capture a set of arguments, inserted immediately after arguments // after the binary.. -void CLI2::add (const std::vector & arguments, int offset /* = 0 */) -{ - std::vector replacement {_original_args.begin(), _original_args.begin() + offset + 1}; +void CLI2::add(const std::vector& arguments, int offset /* = 0 */) { + std::vector replacement{_original_args.begin(), _original_args.begin() + offset + 1}; - for (const auto& arg : arguments) - replacement.emplace_back (arg, Lexer::Type::word); + for (const auto& arg : arguments) replacement.emplace_back(arg, Lexer::Type::word); - for (unsigned int i = 1 + offset; i < _original_args.size (); ++i) - replacement.push_back (_original_args[i]); + for (unsigned int i = 1 + offset; i < _original_args.size(); ++i) + replacement.push_back(_original_args[i]); _original_args = replacement; // Adding a new argument invalidates prior analysis. - _args.clear (); + _args.clear(); } //////////////////////////////////////////////////////////////////////////////// @@ -349,31 +304,25 @@ void CLI2::add (const std::vector & arguments, int offset /* = 0 */ // The binary name is 'task', but if the binary is reported as 'cal' or // 'calendar' then it was invoked via symbolic link, in which case capture the // first argument as 'calendar'. -void CLI2::handleArg0 () -{ +void CLI2::handleArg0() { // Capture arg0 separately, because it is the command that was run, and could // need special handling. - auto raw = _original_args[0].attribute ("raw"); - A2 a (raw, Lexer::Type::word); - a.tag ("BINARY"); + auto raw = _original_args[0].attribute("raw"); + A2 a(raw, Lexer::Type::word); + a.tag("BINARY"); std::string basename = "task"; - auto slash = raw.rfind ('/'); - if (slash != std::string::npos) - basename = raw.substr (slash + 1); + auto slash = raw.rfind('/'); + if (slash != std::string::npos) basename = raw.substr(slash + 1); - a.attribute ("basename", basename); - if (basename == "cal" || - basename == "calendar") - { - _args.push_back (a); + a.attribute("basename", basename); + if (basename == "cal" || basename == "calendar") { + _args.push_back(a); - A2 cal ("calendar", Lexer::Type::word); - _args.push_back (cal); - } - else - { - _args.push_back (a); + A2 cal("calendar", Lexer::Type::word); + _args.push_back(cal); + } else { + _args.push_back(a); } } @@ -383,61 +332,53 @@ void CLI2::handleArg0 () // // As a side effect, tags all arguments after a terminator ('--') with // TERMINATED. -void CLI2::lexArguments () -{ +void CLI2::lexArguments() { // Note: Starts iterating at index 1, because ::handleArg0 has already // processed it. bool terminated = false; - for (unsigned int i = 1; i < _original_args.size (); ++i) - { - bool quoted = Lexer::wasQuoted (_original_args[i].attribute ("raw")); + for (unsigned int i = 1; i < _original_args.size(); ++i) { + bool quoted = Lexer::wasQuoted(_original_args[i].attribute("raw")); // Process single-token arguments. std::string lexeme; Lexer::Type type; - Lexer lex (_original_args[i].attribute ("raw")); - if (lex.token (lexeme, type) && - (lex.isEOS () || // Token goes to EOS - (quoted && type == Lexer::Type::pair))) // Quoted pairs automatically go to EOS + Lexer lex(_original_args[i].attribute("raw")); + if (lex.token(lexeme, type) && + (lex.isEOS() || // Token goes to EOS + (quoted && type == Lexer::Type::pair))) // Quoted pairs automatically go to EOS { - if (! terminated && type == Lexer::Type::separator) + if (!terminated && type == Lexer::Type::separator) terminated = true; else if (terminated) type = Lexer::Type::word; - A2 a (_original_args[i].attribute ("raw"), type); - if (terminated) - a.tag ("TERMINATED"); - if (quoted) - a.tag ("QUOTED"); + A2 a(_original_args[i].attribute("raw"), type); + if (terminated) a.tag("TERMINATED"); + if (quoted) a.tag("QUOTED"); - if (_original_args[i].hasTag ("ORIGINAL")) - a.tag ("ORIGINAL"); + if (_original_args[i].hasTag("ORIGINAL")) a.tag("ORIGINAL"); - _args.push_back (a); + _args.push_back(a); } // Process multiple-token arguments. - else - { + else { const std::string quote = "'"; // Escape unescaped single quotes std::string escaped = ""; // For performance reasons. The escaped string is as long as the original. - escaped.reserve (_original_args[i].attribute ("raw").size ()); + escaped.reserve(_original_args[i].attribute("raw").size()); std::string::size_type cursor = 0; bool nextEscaped = false; - while (int num = utf8_next_char (_original_args[i].attribute ("raw"), cursor)) - { - std::string character = utf8_character (num); + while (int num = utf8_next_char(_original_args[i].attribute("raw"), cursor)) { + std::string character = utf8_character(num); if (!nextEscaped && (character == "\\")) nextEscaped = true; else { - if (character == quote && !nextEscaped) - escaped += "\\"; + if (character == quote && !nextEscaped) escaped += "\\"; nextEscaped = false; } escaped += character; @@ -445,166 +386,141 @@ void CLI2::lexArguments () cursor = 0; std::string word; - if (Lexer::readWord (quote + escaped + quote, quote, cursor, word)) - { - Lexer::dequote (word); - A2 unknown (word, Lexer::Type::word); - if (lex.wasQuoted (_original_args[i].attribute ("raw"))) - unknown.tag ("QUOTED"); + if (Lexer::readWord(quote + escaped + quote, quote, cursor, word)) { + Lexer::dequote(word); + A2 unknown(word, Lexer::Type::word); + if (lex.wasQuoted(_original_args[i].attribute("raw"))) unknown.tag("QUOTED"); - if (_original_args[i].hasTag ("ORIGINAL")) - unknown.tag ("ORIGINAL"); + if (_original_args[i].hasTag("ORIGINAL")) unknown.tag("ORIGINAL"); - _args.push_back (unknown); + _args.push_back(unknown); } // This branch may have no use-case. - else - { - A2 unknown (_original_args[i].attribute ("raw"), Lexer::Type::word); - unknown.tag ("UNKNOWN"); + else { + A2 unknown(_original_args[i].attribute("raw"), Lexer::Type::word); + unknown.tag("UNKNOWN"); - if (lex.wasQuoted (_original_args[i].attribute ("raw"))) - unknown.tag ("QUOTED"); + if (lex.wasQuoted(_original_args[i].attribute("raw"))) unknown.tag("QUOTED"); - if (_original_args[i].hasTag ("ORIGINAL")) - unknown.tag ("ORIGINAL"); + if (_original_args[i].hasTag("ORIGINAL")) unknown.tag("ORIGINAL"); - _args.push_back (unknown); + _args.push_back(unknown); } } } - if (Context::getContext ().config.getInteger ("debug.parser") >= 2) - Context::getContext ().debug (dump ("CLI2::analyze lexArguments")); + if (Context::getContext().config.getInteger("debug.parser") >= 2) + Context::getContext().debug(dump("CLI2::analyze lexArguments")); } //////////////////////////////////////////////////////////////////////////////// // [1] Scan all args for the 'add' and 'log' commands, and demote any // Lexer::Type::Tag args with sign '-' to Lexer::Type::word. // [2] Convert any pseudo args name:value into config settings, and erase. -void CLI2::demotion () -{ +void CLI2::demotion() { bool changes = false; - std::vector replacement; + std::vector replacement; std::string canonical; - for (auto& a : _args) - { - if (a._lextype == Lexer::Type::tag && - a.attribute ("sign") == "-") - { - std::string command = getCommand (); - if (command == "add" || - command == "log") - { + for (auto& a : _args) { + if (a._lextype == Lexer::Type::tag && a.attribute("sign") == "-") { + std::string command = getCommand(); + if (command == "add" || command == "log") { a._lextype = Lexer::Type::word; changes = true; } } else if (a._lextype == Lexer::Type::pair && - canonicalize (canonical, "pseudo", a.attribute ("name"))) - { - Context::getContext ().config.set (canonical, a.attribute ("value")); + canonicalize(canonical, "pseudo", a.attribute("name"))) { + Context::getContext().config.set(canonical, a.attribute("value")); changes = true; // Equivalent to erasing 'a'. continue; } - replacement.push_back (a); + replacement.push_back(a); } - if (changes && - Context::getContext ().config.getInteger ("debug.parser") >= 2) - Context::getContext ().debug (dump ("CLI2::analyze demotion")); + if (changes && Context::getContext().config.getInteger("debug.parser") >= 2) + Context::getContext().debug(dump("CLI2::analyze demotion")); } //////////////////////////////////////////////////////////////////////////////// // Intended to be called after ::add() to perform the final analysis. -void CLI2::analyze () -{ - if (Context::getContext ().config.getInteger ("debug.parser") >= 2) - Context::getContext ().debug (dump ("CLI2::analyze")); +void CLI2::analyze() { + if (Context::getContext().config.getInteger("debug.parser") >= 2) + Context::getContext().debug(dump("CLI2::analyze")); // Process _original_args. - _args.clear (); - handleArg0 (); - lexArguments (); + _args.clear(); + handleArg0(); + lexArguments(); // Process _args. - aliasExpansion (); - if (! findCommand ()) - { - defaultCommand (); - if (! findCommand ()) - throw std::string ("You must specify a command or a task to modify."); + aliasExpansion(); + if (!findCommand()) { + defaultCommand(); + if (!findCommand()) throw std::string("You must specify a command or a task to modify."); } - demotion (); - canonicalizeNames (); + demotion(); + canonicalizeNames(); // Determine arg types: FILTER, MODIFICATION, MISCELLANEOUS. - categorizeArgs (); - parenthesizeOriginalFilter (); + categorizeArgs(); + parenthesizeOriginalFilter(); // Cache frequently looked up items - _command = getCommand (); + _command = getCommand(); } //////////////////////////////////////////////////////////////////////////////// // Process raw filter string. // Insert filter arguments (wrapped in parentheses) immediatelly after the binary. -void CLI2::addFilter (const std::string& arg) -{ - if (arg.length ()) - { - std::vector filter; - filter.push_back ("("); +void CLI2::addFilter(const std::string& arg) { + if (arg.length()) { + std::vector filter; + filter.push_back("("); std::string lexeme; Lexer::Type type; - Lexer lex (arg); + Lexer lex(arg); - while (lex.token (lexeme, type)) - filter.push_back (lexeme); + while (lex.token(lexeme, type)) filter.push_back(lexeme); - filter.push_back (")"); - add (filter); - analyze (); + filter.push_back(")"); + add(filter); + analyze(); } } //////////////////////////////////////////////////////////////////////////////// // Process raw modification string. // Insert modification arguments immediatelly after the command (i.e. 'add') -void CLI2::addModifications (const std::string& arg) -{ - if (arg.length ()) - { - std::vector mods; +void CLI2::addModifications(const std::string& arg) { + if (arg.length()) { + std::vector mods; std::string lexeme; Lexer::Type type; - Lexer lex (arg); + Lexer lex(arg); - while (lex.token (lexeme, type)) - mods.push_back (lexeme); + while (lex.token(lexeme, type)) mods.push_back(lexeme); // Determine at which argument index does the task modification command // reside unsigned int cmdIndex = 0; - for (; cmdIndex < _args.size(); ++cmdIndex) - { + for (; cmdIndex < _args.size(); ++cmdIndex) { // Command found, stop iterating. - if (_args[cmdIndex].hasTag ("CMD")) - break; + if (_args[cmdIndex].hasTag("CMD")) break; } // Insert modifications after the command. - add (mods, cmdIndex); - analyze (); + add(mods, cmdIndex); + analyze(); } } @@ -612,35 +528,30 @@ void CLI2::addModifications (const std::string& arg) // There are situations where a context filter is applied. This method // determines whether one applies, and if so, applies it. Disqualifiers include: // - filter contains ID or UUID -void CLI2::addContext (bool readable, bool writeable) -{ +void CLI2::addContext(bool readable, bool writeable) { // Recursion block. - if (_context_added) - return; + if (_context_added) return; // Detect if any context is set, and bail out if not std::string contextString; if (readable) // Empty string is treated as "currently selected context" - contextString = Context::getContext ().getTaskContext("read", ""); + contextString = Context::getContext().getTaskContext("read", ""); else if (writeable) - contextString = Context::getContext ().getTaskContext("write", ""); + contextString = Context::getContext().getTaskContext("write", ""); else return; // If context is empty, bail out too - if (contextString.empty ()) - return; + if (contextString.empty()) return; // For readable contexts: Detect if UUID or ID is set, and bail out if (readable) - for (auto& a : _args) - { - if (a._lextype == Lexer::Type::uuid || - a._lextype == Lexer::Type::number || - a._lextype == Lexer::Type::set) - { - Context::getContext ().debug (format ("UUID/ID argument found '{1}', not applying context.", a.attribute ("raw"))); + for (auto& a : _args) { + if (a._lextype == Lexer::Type::uuid || a._lextype == Lexer::Type::number || + a._lextype == Lexer::Type::set) { + Context::getContext().debug( + format("UUID/ID argument found '{1}', not applying context.", a.attribute("raw"))); return; } } @@ -649,75 +560,63 @@ void CLI2::addContext (bool readable, bool writeable) // block now, since addFilter calls analyze(), which calls addContext(). _context_added = true; if (readable) - addFilter (contextString); + addFilter(contextString); else if (writeable) - addModifications (contextString); + addModifications(contextString); // Inform the user about the application of context - if (Context::getContext ().verbose ("context")) - Context::getContext ().footnote (format ( - "Context '{1}' set. Use 'task context none' to remove.", - Context::getContext ().config.get ("context") - )); + if (Context::getContext().verbose("context")) + Context::getContext().footnote(format("Context '{1}' set. Use 'task context none' to remove.", + Context::getContext().config.get("context"))); } //////////////////////////////////////////////////////////////////////////////// // Parse the command line, identifiying filter components, expanding syntactic // sugar as necessary. -void CLI2::prepareFilter () -{ +void CLI2::prepareFilter() { // Clear and re-populate. - _id_ranges.clear (); - _uuid_list.clear (); + _id_ranges.clear(); + _uuid_list.clear(); _context_added = false; // Remove all the syntactic sugar for FILTERs. - lexFilterArgs (); - findIDs (); - findUUIDs (); - insertIDExpr (); - desugarFilterPlainArgs (); - findStrayModifications (); - desugarFilterTags (); - desugarFilterAttributes (); - desugarFilterPatterns (); - insertJunctions (); // Deliberately after all desugar calls. + lexFilterArgs(); + findIDs(); + findUUIDs(); + insertIDExpr(); + desugarFilterPlainArgs(); + findStrayModifications(); + desugarFilterTags(); + desugarFilterAttributes(); + desugarFilterPatterns(); + insertJunctions(); // Deliberately after all desugar calls. - if (Context::getContext ().verbose ("filter")) - { + if (Context::getContext().verbose("filter")) { std::string combined; - for (const auto& a : _args) - { - if (a.hasTag ("FILTER")) - { - if (combined != "") - combined += ' '; + for (const auto& a : _args) { + if (a.hasTag("FILTER")) { + if (combined != "") combined += ' '; - combined += a.attribute ("raw"); + combined += a.attribute("raw"); } } - if (combined.size ()) - Context::getContext ().footnote (std::string ("Filter: ") + combined); + if (combined.size()) Context::getContext().footnote(std::string("Filter: ") + combined); } } //////////////////////////////////////////////////////////////////////////////// // Return all the MISCELLANEOUS args as strings. -const std::vector CLI2::getWords () -{ - std::vector words; +const std::vector CLI2::getWords() { + std::vector words; for (const auto& a : _args) - if (a.hasTag ("MISCELLANEOUS")) - words.push_back (a.attribute ("raw")); + if (a.hasTag("MISCELLANEOUS")) words.push_back(a.attribute("raw")); - if (Context::getContext ().config.getInteger ("debug.parser") >= 2) - { - Color colorOrigArgs ("gray10 on gray4"); + if (Context::getContext().config.getInteger("debug.parser") >= 2) { + Color colorOrigArgs("gray10 on gray4"); std::string message = " "; - for (const auto& word : words) - message += colorOrigArgs.colorize (word) + ' '; - Context::getContext ().debug ("CLI2::getWords" + message); + for (const auto& word : words) message += colorOrigArgs.colorize(word) + ' '; + Context::getContext().debug("CLI2::getWords" + message); } return words; @@ -725,54 +624,45 @@ const std::vector CLI2::getWords () //////////////////////////////////////////////////////////////////////////////// // Return all the MISCELLANEOUS args. -const std::vector CLI2::getMiscellaneous () -{ - std::vector misc; +const std::vector CLI2::getMiscellaneous() { + std::vector misc; for (const auto& a : _args) - if (a.hasTag ("MISCELLANEOUS")) - misc.push_back (a); + if (a.hasTag("MISCELLANEOUS")) misc.push_back(a); return misc; } //////////////////////////////////////////////////////////////////////////////// // Search for 'value' in _entities category, return canonicalized value. -bool CLI2::canonicalize ( - std::string& canonicalized, - const std::string& category, - const std::string& value) -{ +bool CLI2::canonicalize(std::string& canonicalized, const std::string& category, + const std::string& value) { // Utilize a cache mapping of (category, value) -> canonicalized value. // This cache does not need to be invalidated, because entities are defined // only once per initialization of the Context object. - int cache_key = 31 * std::hash{} (category) + std::hash{} (value); - auto cache_result = _canonical_cache.find (cache_key); - if (cache_result != _canonical_cache.end()) - { + int cache_key = 31 * std::hash{}(category) + std::hash{}(value); + auto cache_result = _canonical_cache.find(cache_key); + if (cache_result != _canonical_cache.end()) { canonicalized = cache_result->second; return true; } // Extract a list of entities for category. - std::vector options; - auto c = _entities.equal_range (category); - for (auto e = c.first; e != c.second; ++e) - { + std::vector options; + auto c = _entities.equal_range(category); + for (auto e = c.first; e != c.second; ++e) { // Shortcut: if an exact match is found, success. - if (value == e->second) - { + if (value == e->second) { canonicalized = value; _canonical_cache[cache_key] = value; return true; } - options.push_back (e->second); + options.push_back(e->second); } // Match against the options, throw away results. - std::vector matches; - if (autoComplete (value, options, matches, minimumMatchLength) == 1) - { + std::vector matches; + if (autoComplete(value, options, matches, minimumMatchLength) == 1) { canonicalized = matches[0]; _canonical_cache[cache_key] = matches[0]; return true; @@ -782,186 +672,144 @@ bool CLI2::canonicalize ( } //////////////////////////////////////////////////////////////////////////////// -std::string CLI2::getBinary () const -{ - if (_args.size ()) - return _args[0].attribute ("raw"); +std::string CLI2::getBinary() const { + if (_args.size()) return _args[0].attribute("raw"); return ""; } //////////////////////////////////////////////////////////////////////////////// -std::string CLI2::getCommand (bool canonical) const -{ +std::string CLI2::getCommand(bool canonical) const { // Shortcut if analysis has been finalized - if (_command != "") - return _command; + if (_command != "") return _command; for (const auto& a : _args) - if (a.hasTag ("CMD")) - return a.attribute (canonical ? "canonical" : "raw"); + if (a.hasTag("CMD")) return a.attribute(canonical ? "canonical" : "raw"); return ""; } //////////////////////////////////////////////////////////////////////////////// -const std::string CLI2::dump (const std::string& title) const -{ +const std::string CLI2::dump(const std::string& title) const { std::stringstream out; out << "\033[1m" << title << "\033[0m\n" << " _original_args\n "; - Color colorArgs ("gray10 on gray4"); - Color colorFilter ("black on rgb311"); - for (auto i = _original_args.begin (); i != _original_args.end (); ++i) - { - if (i != _original_args.begin ()) - out << ' '; + Color colorArgs("gray10 on gray4"); + Color colorFilter("black on rgb311"); + for (auto i = _original_args.begin(); i != _original_args.end(); ++i) { + if (i != _original_args.begin()) out << ' '; - if (i->hasTag ("ORIGINAL")) - out << colorArgs.colorize (i->attribute ("raw")); + if (i->hasTag("ORIGINAL")) + out << colorArgs.colorize(i->attribute("raw")); else - out << colorFilter.colorize (i->attribute ("raw")); + out << colorFilter.colorize(i->attribute("raw")); } out << '\n'; - if (_args.size ()) - { + if (_args.size()) { out << " _args\n"; - for (const auto& a : _args) - out << " " << a.dump () << '\n'; + for (const auto& a : _args) out << " " << a.dump() << '\n'; } - if (_id_ranges.size ()) - { + if (_id_ranges.size()) { out << " _id_ranges\n "; - for (const auto& range : _id_ranges) - { + for (const auto& range : _id_ranges) { if (range.first != range.second) - out << colorArgs.colorize (range.first + "-" + range.second) << ' '; + out << colorArgs.colorize(range.first + "-" + range.second) << ' '; else - out << colorArgs.colorize (range.first) << ' '; + out << colorArgs.colorize(range.first) << ' '; } out << '\n'; } - if (_uuid_list.size ()) - { + if (_uuid_list.size()) { out << " _uuid_list\n "; - for (const auto& uuid : _uuid_list) - out << colorArgs.colorize (uuid) << ' '; + for (const auto& uuid : _uuid_list) out << colorArgs.colorize(uuid) << ' '; out << '\n'; } - return out.str (); + return out.str(); } //////////////////////////////////////////////////////////////////////////////// // If any aliases are found in un-TERMINATED arguments, replace the alias with // a set of Lexed tokens from the configuration. -void CLI2::aliasExpansion () -{ +void CLI2::aliasExpansion() { bool changes = false; bool action; int counter = 0; - do - { + do { action = false; - std::vector reconstructed; + std::vector reconstructed; std::string raw; - for (const auto& i : _args) - { - raw = i.attribute ("raw"); - if (i.hasTag ("TERMINATED")) - { - reconstructed.push_back (i); - } - else if (_aliases.find (raw) != _aliases.end ()) - { + for (const auto& i : _args) { + raw = i.attribute("raw"); + if (i.hasTag("TERMINATED")) { + reconstructed.push_back(i); + } else if (_aliases.find(raw) != _aliases.end()) { std::string lexeme; Lexer::Type type; - Lexer lex (_aliases[raw]); - while (lex.token (lexeme, type)) - reconstructed.emplace_back (lexeme, type); + Lexer lex(_aliases[raw]); + while (lex.token(lexeme, type)) reconstructed.emplace_back(lexeme, type); action = true; changes = true; - } - else - { - reconstructed.push_back (i); + } else { + reconstructed.push_back(i); } } _args = reconstructed; - std::vector reconstructedOriginals; + std::vector reconstructedOriginals; bool terminated = false; - for (const auto& i : _original_args) - { - if (i.attribute ("raw") == "--") - terminated = true; + for (const auto& i : _original_args) { + if (i.attribute("raw") == "--") terminated = true; - if (terminated) - { - reconstructedOriginals.push_back (i); - } - else if (_aliases.find (i.attribute ("raw")) != _aliases.end ()) - { + if (terminated) { + reconstructedOriginals.push_back(i); + } else if (_aliases.find(i.attribute("raw")) != _aliases.end()) { std::string lexeme; Lexer::Type type; - Lexer lex (_aliases[i.attribute ("raw")]); - while (lex.token (lexeme, type)) - reconstructedOriginals.emplace_back (lexeme, type); + Lexer lex(_aliases[i.attribute("raw")]); + while (lex.token(lexeme, type)) reconstructedOriginals.emplace_back(lexeme, type); action = true; changes = true; - } - else - { - reconstructedOriginals.push_back (i); + } else { + reconstructedOriginals.push_back(i); } } _original_args = reconstructedOriginals; - } - while (action && counter++ < safetyValveDefault); + } while (action && counter++ < safetyValveDefault); if (counter >= safetyValveDefault) - Context::getContext ().debug (format ("Nested alias limit of {1} reached.", safetyValveDefault)); + Context::getContext().debug(format("Nested alias limit of {1} reached.", safetyValveDefault)); - if (changes && - Context::getContext ().config.getInteger ("debug.parser") >= 2) - Context::getContext ().debug (dump ("CLI2::analyze aliasExpansion")); + if (changes && Context::getContext().config.getInteger("debug.parser") >= 2) + Context::getContext().debug(dump("CLI2::analyze aliasExpansion")); } //////////////////////////////////////////////////////////////////////////////// // Scan all arguments and canonicalize names that need it. -void CLI2::canonicalizeNames () -{ +void CLI2::canonicalizeNames() { bool changes = false; - for (auto& a : _args) - { - if (a._lextype == Lexer::Type::pair) - { - std::string raw = a.attribute ("raw"); - if (raw.substr (0, 3) != "rc:" && - raw.substr (0, 3) != "rc.") - { - std::string name = a.attribute ("name"); + for (auto& a : _args) { + if (a._lextype == Lexer::Type::pair) { + std::string raw = a.attribute("raw"); + if (raw.substr(0, 3) != "rc:" && raw.substr(0, 3) != "rc.") { + std::string name = a.attribute("name"); std::string canonical; - if (canonicalize (canonical, "pseudo", name) || - canonicalize (canonical, "attribute", name)) - { - a.attribute ("canonical", canonical); - } - else - { + if (canonicalize(canonical, "pseudo", name) || canonicalize(canonical, "attribute", name)) { + a.attribute("canonical", canonical); + } else { a._lextype = Lexer::Type::word; } @@ -970,18 +818,16 @@ void CLI2::canonicalizeNames () } } - if (changes && - Context::getContext ().config.getInteger ("debug.parser") >= 2) - Context::getContext ().debug (dump ("CLI2::analyze canonicalizeNames")); + if (changes && Context::getContext().config.getInteger("debug.parser") >= 2) + Context::getContext().debug(dump("CLI2::analyze canonicalizeNames")); } //////////////////////////////////////////////////////////////////////////////// // Categorize FILTER, MODIFICATION and MISCELLANEOUS args, based on CMD DNA. -void CLI2::categorizeArgs () -{ +void CLI2::categorizeArgs() { // Context is only applied for commands that request it. - std::string command = getCommand (); - Command* cmd = Context::getContext ().commands[command]; + std::string command = getCommand(); + Command* cmd = Context::getContext().commands[command]; // Determine if the command uses Context. CmdCustom and CmdTimesheet need to // be handled separately, as they override the parent Command::use_context @@ -990,35 +836,28 @@ void CLI2::categorizeArgs () // All Command classes overriding uses_context () getter need to be specified // here. bool uses_context; - if (dynamic_cast (cmd)) - uses_context = (dynamic_cast (cmd))->uses_context (); - else if (dynamic_cast (cmd)) - uses_context = (dynamic_cast (cmd))->uses_context (); + if (dynamic_cast(cmd)) + uses_context = (dynamic_cast(cmd))->uses_context(); + else if (dynamic_cast(cmd)) + uses_context = (dynamic_cast(cmd))->uses_context(); else if (cmd) - uses_context = cmd->uses_context (); + uses_context = cmd->uses_context(); // Apply the context, if applicable - if (cmd && uses_context) - addContext (cmd->accepts_filter (), cmd->accepts_modifications ()); + if (cmd && uses_context) addContext(cmd->accepts_filter(), cmd->accepts_modifications()); bool changes = false; bool afterCommand = false; - for (auto& a : _args) - { - if (a._lextype == Lexer::Type::separator) - continue; + for (auto& a : _args) { + if (a._lextype == Lexer::Type::separator) continue; // Record that the command has been found, it affects behavior. - if (a.hasTag ("CMD")) - { + if (a.hasTag("CMD")) { afterCommand = true; } // Skip admin args. - else if (a.hasTag ("BINARY") || - a.hasTag ("RC") || - a.hasTag ("CONFIG")) - { + else if (a.hasTag("BINARY") || a.hasTag("RC") || a.hasTag("CONFIG")) { // NOP. } @@ -1033,83 +872,51 @@ void CLI2::categorizeArgs () // Fi Mo -- task [Fi] [Mo] // Fi Mo Mi Internally inconsistent // - else if (cmd && - ! cmd->accepts_filter () && - ! cmd->accepts_modifications () && - ! cmd->accepts_miscellaneous ()) - { + else if (cmd && !cmd->accepts_filter() && !cmd->accepts_modifications() && + !cmd->accepts_miscellaneous()) { // No commands were expected --> error. - throw format ("The '{1}' command does not allow '{2}'.", command, a.attribute ("raw")); - } - else if (cmd && - ! cmd->accepts_filter () && - ! cmd->accepts_modifications () && - cmd->accepts_miscellaneous ()) - { - a.tag ("MISCELLANEOUS"); + throw format("The '{1}' command does not allow '{2}'.", command, a.attribute("raw")); + } else if (cmd && !cmd->accepts_filter() && !cmd->accepts_modifications() && + cmd->accepts_miscellaneous()) { + a.tag("MISCELLANEOUS"); changes = true; - } - else if (cmd && - ! cmd->accepts_filter () && - cmd->accepts_modifications () && - ! cmd->accepts_miscellaneous ()) - { - a.tag ("MODIFICATION"); + } else if (cmd && !cmd->accepts_filter() && cmd->accepts_modifications() && + !cmd->accepts_miscellaneous()) { + a.tag("MODIFICATION"); changes = true; - } - else if (cmd && - ! cmd->accepts_filter () && - cmd->accepts_modifications () && - cmd->accepts_miscellaneous ()) - { + } else if (cmd && !cmd->accepts_filter() && cmd->accepts_modifications() && + cmd->accepts_miscellaneous()) { // Error: internally inconsistent. - throw std::string ("Unknown error. Please report."); - } - else if (cmd && - cmd->accepts_filter () && - ! cmd->accepts_modifications () && - ! cmd->accepts_miscellaneous ()) - { - a.tag ("FILTER"); + throw std::string("Unknown error. Please report."); + } else if (cmd && cmd->accepts_filter() && !cmd->accepts_modifications() && + !cmd->accepts_miscellaneous()) { + a.tag("FILTER"); changes = true; - } - else if (cmd && - cmd->accepts_filter () && - ! cmd->accepts_modifications () && - cmd->accepts_miscellaneous ()) - { + } else if (cmd && cmd->accepts_filter() && !cmd->accepts_modifications() && + cmd->accepts_miscellaneous()) { if (!afterCommand) - a.tag ("FILTER"); + a.tag("FILTER"); else - a.tag ("MISCELLANEOUS"); + a.tag("MISCELLANEOUS"); changes = true; - } - else if (cmd && - cmd->accepts_filter () && - cmd->accepts_modifications () && - ! cmd->accepts_miscellaneous ()) - { + } else if (cmd && cmd->accepts_filter() && cmd->accepts_modifications() && + !cmd->accepts_miscellaneous()) { if (!afterCommand) - a.tag ("FILTER"); + a.tag("FILTER"); else - a.tag ("MODIFICATION"); + a.tag("MODIFICATION"); changes = true; - } - else if (cmd && - cmd->accepts_filter () && - cmd->accepts_modifications () && - cmd->accepts_miscellaneous ()) - { + } else if (cmd && cmd->accepts_filter() && cmd->accepts_modifications() && + cmd->accepts_miscellaneous()) { // Error: internally inconsistent. - throw std::string ("Unknown error. Please report."); + throw std::string("Unknown error. Please report."); } } - if (changes && - Context::getContext ().config.getInteger ("debug.parser") >= 2) - Context::getContext ().debug (dump ("CLI2::analyze categorizeArgs")); + if (changes && Context::getContext().config.getInteger("debug.parser") >= 2) + Context::getContext().debug(dump("CLI2::analyze categorizeArgs")); } //////////////////////////////////////////////////////////////////////////////// @@ -1132,53 +939,43 @@ void CLI2::categorizeArgs () // task ( status:pending ) and ( +home or +work ) list // // the query is correct. -void CLI2::parenthesizeOriginalFilter () -{ +void CLI2::parenthesizeOriginalFilter() { // Locate the first and last ORIGINAL FILTER args. unsigned int firstOriginalFilter = 0; unsigned int lastOriginalFilter = 0; - for (unsigned int i = 1; i < _args.size (); ++i) - { - if (_args[i].hasTag ("FILTER") && - _args[i].hasTag ("ORIGINAL")) - { - if (firstOriginalFilter == 0) - firstOriginalFilter = i; + for (unsigned int i = 1; i < _args.size(); ++i) { + if (_args[i].hasTag("FILTER") && _args[i].hasTag("ORIGINAL")) { + if (firstOriginalFilter == 0) firstOriginalFilter = i; lastOriginalFilter = i; } } // If found, parenthesize the arg list accordingly. - if (firstOriginalFilter && - lastOriginalFilter) - { - std::vector reconstructed; - for (unsigned int i = 0; i < _args.size (); ++i) - { - if (i == firstOriginalFilter) - { - A2 openParen ("(", Lexer::Type::op); - openParen.tag ("ORIGINAL"); - openParen.tag ("FILTER"); - reconstructed.push_back (openParen); + if (firstOriginalFilter && lastOriginalFilter) { + std::vector reconstructed; + for (unsigned int i = 0; i < _args.size(); ++i) { + if (i == firstOriginalFilter) { + A2 openParen("(", Lexer::Type::op); + openParen.tag("ORIGINAL"); + openParen.tag("FILTER"); + reconstructed.push_back(openParen); } - reconstructed.push_back (_args[i]); + reconstructed.push_back(_args[i]); - if (i == lastOriginalFilter) - { - A2 closeParen (")", Lexer::Type::op); - closeParen.tag ("ORIGINAL"); - closeParen.tag ("FILTER"); - reconstructed.push_back (closeParen); + if (i == lastOriginalFilter) { + A2 closeParen(")", Lexer::Type::op); + closeParen.tag("ORIGINAL"); + closeParen.tag("FILTER"); + reconstructed.push_back(closeParen); } } _args = reconstructed; - if (Context::getContext ().config.getInteger ("debug.parser") >= 2) - Context::getContext ().debug (dump ("CLI2::analyze parenthesizeOriginalFilter")); + if (Context::getContext().config.getInteger("debug.parser") >= 2) + Context::getContext().debug(dump("CLI2::analyze parenthesizeOriginalFilter")); } } @@ -1186,11 +983,9 @@ void CLI2::parenthesizeOriginalFilter () // Scan all arguments and if any are an exact match for a command name, then // tag as CMD. If an argument is an exact match for an attribute, despite being // an inexact match for a command, then it is not a command. -bool CLI2::findCommand () -{ - for (auto& a : _args) - { - std::string raw = a.attribute ("raw"); +bool CLI2::findCommand() { + for (auto& a : _args) { + std::string raw = a.attribute("raw"); std::string canonical; // If the arg canonicalized to a 'cmd', but is also not an exact match @@ -1198,28 +993,28 @@ bool CLI2::findCommand () // task project=foo list // ^cmd ^cmd // ^attribute - if (exactMatch ("cmd", raw)) + if (exactMatch("cmd", raw)) canonical = raw; - else if (exactMatch ("attribute", raw)) + else if (exactMatch("attribute", raw)) continue; - else if (! canonicalize (canonical, "cmd", raw)) + else if (!canonicalize(canonical, "cmd", raw)) continue; - a.attribute ("canonical", canonical); - a.tag ("CMD"); + a.attribute("canonical", canonical); + a.tag("CMD"); // Apply command DNA as tags. - Command* command = Context::getContext ().commands[canonical]; - if (command->read_only ()) a.tag ("READONLY"); - if (command->displays_id ()) a.tag ("SHOWSID"); - if (command->needs_gc ()) a.tag ("RUNSGC"); - if (command->uses_context ()) a.tag ("USESCONTEXT"); - if (command->accepts_filter ()) a.tag ("ALLOWSFILTER"); - if (command->accepts_modifications ()) a.tag ("ALLOWSMODIFICATIONS"); - if (command->accepts_miscellaneous ()) a.tag ("ALLOWSMISC"); + Command* command = Context::getContext().commands[canonical]; + if (command->read_only()) a.tag("READONLY"); + if (command->displays_id()) a.tag("SHOWSID"); + if (command->needs_gc()) a.tag("RUNSGC"); + if (command->uses_context()) a.tag("USESCONTEXT"); + if (command->accepts_filter()) a.tag("ALLOWSFILTER"); + if (command->accepts_modifications()) a.tag("ALLOWSMODIFICATIONS"); + if (command->accepts_miscellaneous()) a.tag("ALLOWSMISC"); - if (Context::getContext ().config.getInteger ("debug.parser") >= 2) - Context::getContext ().debug (dump ("CLI2::analyze findCommand")); + if (Context::getContext().config.getInteger("debug.parser") >= 2) + Context::getContext().debug(dump("CLI2::analyze findCommand")); // Stop and indicate command found. return true; @@ -1231,15 +1026,11 @@ bool CLI2::findCommand () //////////////////////////////////////////////////////////////////////////////// // Search for exact 'value' in _entities category. -bool CLI2::exactMatch ( - const std::string& category, - const std::string& value) const -{ +bool CLI2::exactMatch(const std::string& category, const std::string& value) const { // Extract a list of entities for category. - auto c = _entities.equal_range (category); + auto c = _entities.equal_range(category); for (auto e = c.first; e != c.second; ++e) - if (value == e->second) - return true; + if (value == e->second) return true; return false; } @@ -1247,90 +1038,74 @@ bool CLI2::exactMatch ( //////////////////////////////////////////////////////////////////////////////// // +tag --> tags _hastag_ tag // -tag --> tags _notag_ tag -void CLI2::desugarFilterTags () -{ +void CLI2::desugarFilterTags() { bool changes = false; - std::vector reconstructed; - for (const auto& a : _args) - { - if (a._lextype == Lexer::Type::tag && - a.hasTag ("FILTER")) - { + std::vector reconstructed; + for (const auto& a : _args) { + if (a._lextype == Lexer::Type::tag && a.hasTag("FILTER")) { changes = true; - A2 left ("tags", Lexer::Type::dom); - left.tag ("FILTER"); - reconstructed.push_back (left); + A2 left("tags", Lexer::Type::dom); + left.tag("FILTER"); + reconstructed.push_back(left); - std::string raw = a.attribute ("raw"); + std::string raw = a.attribute("raw"); - A2 op (raw[0] == '+' ? "_hastag_" : "_notag_", Lexer::Type::op); - op.tag ("FILTER"); - reconstructed.push_back (op); + A2 op(raw[0] == '+' ? "_hastag_" : "_notag_", Lexer::Type::op); + op.tag("FILTER"); + reconstructed.push_back(op); - A2 right ("" + raw.substr (1) + "", Lexer::Type::string); - right.tag ("FILTER"); - reconstructed.push_back (right); - } - else - reconstructed.push_back (a); + A2 right("" + raw.substr(1) + "", Lexer::Type::string); + right.tag("FILTER"); + reconstructed.push_back(right); + } else + reconstructed.push_back(a); } - if (changes) - { + if (changes) { _args = reconstructed; - if (Context::getContext ().config.getInteger ("debug.parser") >= 2) - Context::getContext ().debug (dump ("CLI2::prepareFilter desugarFilterTags")); + if (Context::getContext().config.getInteger("debug.parser") >= 2) + Context::getContext().debug(dump("CLI2::prepareFilter desugarFilterTags")); } } //////////////////////////////////////////////////////////////////////////////// -void CLI2::findStrayModifications () -{ +void CLI2::findStrayModifications() { bool changes = false; - auto command = getCommand (); - if (command == "add" || - command == "log") - { - for (auto& a : _args) - { - if (a.hasTag ("FILTER")) - { - a.unTag ("FILTER"); - a.tag ("MODIFICATION"); + auto command = getCommand(); + if (command == "add" || command == "log") { + for (auto& a : _args) { + if (a.hasTag("FILTER")) { + a.unTag("FILTER"); + a.tag("MODIFICATION"); changes = true; } } } if (changes) - if (Context::getContext ().config.getInteger ("debug.parser") >= 2) - Context::getContext ().debug (dump ("CLI2::prepareFilter findStrayModifications")); + if (Context::getContext().config.getInteger("debug.parser") >= 2) + Context::getContext().debug(dump("CLI2::prepareFilter findStrayModifications")); } //////////////////////////////////////////////////////////////////////////////// // [.]:['"][]['"] --> name value -void CLI2::desugarFilterAttributes () -{ +void CLI2::desugarFilterAttributes() { bool changes = false; - std::vector reconstructed; - for (auto& a : _args) - { - if (a._lextype == Lexer::Type::pair && - a.hasTag ("FILTER")) - { - std::string raw = a.attribute ("raw"); - std::string name = a.attribute ("name"); - std::string mod = a.attribute ("modifier"); - std::string sep = a.attribute ("separator"); - std::string value = a.attribute ("value"); + std::vector reconstructed; + for (auto& a : _args) { + if (a._lextype == Lexer::Type::pair && a.hasTag("FILTER")) { + std::string raw = a.attribute("raw"); + std::string name = a.attribute("name"); + std::string mod = a.attribute("modifier"); + std::string sep = a.attribute("separator"); + std::string value = a.attribute("value"); // An unquoted string, while equivalent to an empty string, doesn't cause // an operand shortage in eval. - if (value == "") - value = "''"; + if (value == "") value = "''"; // Some values are expressions, which need to be lexed. The best way to // determine whether an expression is either a single value, or needs to @@ -1343,151 +1118,111 @@ void CLI2::desugarFilterAttributes () // 1d // ) // Use this sequence in place of a single value. - std::vector values = lexExpression (value); - if (Context::getContext ().config.getInteger ("debug.parser") >= 2) - { - Context::getContext ().debug ("CLI2::lexExpression " + name + ':' + value); - for (auto& v : values) - Context::getContext ().debug (" " + v.dump ()); - Context::getContext ().debug (" "); + std::vector values = lexExpression(value); + if (Context::getContext().config.getInteger("debug.parser") >= 2) { + Context::getContext().debug("CLI2::lexExpression " + name + ':' + value); + for (auto& v : values) Context::getContext().debug(" " + v.dump()); + Context::getContext().debug(" "); } bool found = false; std::string canonical; - if (canonicalize (canonical, "attribute", name)) - { + if (canonicalize(canonical, "attribute", name)) { // Certain attribute types do not suport math. // string --> no // numeric --> yes // date --> yes // duration --> yes bool evalSupported = true; - Column* col = Context::getContext ().columns[canonical]; - if (col && col->type () == "string") - evalSupported = false; + Column* col = Context::getContext().columns[canonical]; + if (col && col->type() == "string") evalSupported = false; - A2 lhs (name, Lexer::Type::dom); - lhs.tag ("FILTER"); - lhs.attribute ("canonical", canonical); - lhs.attribute ("modifier", mod); + A2 lhs(name, Lexer::Type::dom); + lhs.tag("FILTER"); + lhs.attribute("canonical", canonical); + lhs.attribute("modifier", mod); - A2 op ("", Lexer::Type::op); - op.tag ("FILTER"); + A2 op("", Lexer::Type::op); + op.tag("FILTER"); // Attribute types that do not support evaluation should be interpreted // as strings (currently this means that string attributes are not evaluated) - A2 rhs ("", evalSupported ? values[0]._lextype: Lexer::Type::string); - rhs.tag ("FILTER"); + A2 rhs("", evalSupported ? values[0]._lextype : Lexer::Type::string); + rhs.tag("FILTER"); // Special case for ':'. - if (mod == "") - { - op.attribute ("raw", "="); - rhs.attribute ("raw", value); - } - else if (mod == "before" || mod == "under" || mod == "below") - { - op.attribute ("raw", "<"); - rhs.attribute ("raw", value); - } - else if (mod == "after" || mod == "over" || mod == "above") - { - op.attribute ("raw", ">"); - rhs.attribute ("raw", value); - } - else if (mod == "by") - { - op.attribute ("raw", "<="); - rhs.attribute ("raw", value); - } - else if (mod == "none") - { - op.attribute ("raw", "=="); - rhs.attribute ("raw", "''"); - } - else if (mod == "any") - { - op.attribute ("raw", "!=="); - rhs.attribute ("raw", "''"); - } - else if (mod == "is" || mod == "equals") - { - op.attribute ("raw", "=="); - rhs.attribute ("raw", value); - } - else if (mod == "not") - { - op.attribute ("raw", "!="); - rhs.attribute ("raw", value); - } - else if (mod == "isnt") - { - op.attribute ("raw", "!=="); - rhs.attribute ("raw", value); - } - else if (mod == "has" || mod == "contains") - { - op.attribute ("raw", "~"); - rhs.attribute ("raw", value); - } - else if (mod == "hasnt") - { - op.attribute ("raw", "!~"); - rhs.attribute ("raw", value); - } - else if (mod == "startswith" || mod == "left") - { - op.attribute ("raw", "~"); - rhs.attribute ("raw", "^" + value); - } - else if (mod == "endswith" || mod == "right") - { - op.attribute ("raw", "~"); - rhs.attribute ("raw", value + "$"); - } - else if (mod == "word") - { - op.attribute ("raw", "~"); -#if defined (DARWIN) - rhs.attribute ("raw", value); -#elif defined (SOLARIS) - rhs.attribute ("raw", "\\<" + value + "\\>"); + if (mod == "") { + op.attribute("raw", "="); + rhs.attribute("raw", value); + } else if (mod == "before" || mod == "under" || mod == "below") { + op.attribute("raw", "<"); + rhs.attribute("raw", value); + } else if (mod == "after" || mod == "over" || mod == "above") { + op.attribute("raw", ">"); + rhs.attribute("raw", value); + } else if (mod == "by") { + op.attribute("raw", "<="); + rhs.attribute("raw", value); + } else if (mod == "none") { + op.attribute("raw", "=="); + rhs.attribute("raw", "''"); + } else if (mod == "any") { + op.attribute("raw", "!=="); + rhs.attribute("raw", "''"); + } else if (mod == "is" || mod == "equals") { + op.attribute("raw", "=="); + rhs.attribute("raw", value); + } else if (mod == "not") { + op.attribute("raw", "!="); + rhs.attribute("raw", value); + } else if (mod == "isnt") { + op.attribute("raw", "!=="); + rhs.attribute("raw", value); + } else if (mod == "has" || mod == "contains") { + op.attribute("raw", "~"); + rhs.attribute("raw", value); + } else if (mod == "hasnt") { + op.attribute("raw", "!~"); + rhs.attribute("raw", value); + } else if (mod == "startswith" || mod == "left") { + op.attribute("raw", "~"); + rhs.attribute("raw", "^" + value); + } else if (mod == "endswith" || mod == "right") { + op.attribute("raw", "~"); + rhs.attribute("raw", value + "$"); + } else if (mod == "word") { + op.attribute("raw", "~"); +#if defined(DARWIN) + rhs.attribute("raw", value); +#elif defined(SOLARIS) + rhs.attribute("raw", "\\<" + value + "\\>"); #else - rhs.attribute ("raw", "\\b" + value + "\\b"); + rhs.attribute("raw", "\\b" + value + "\\b"); #endif - } - else if (mod == "noword") - { - op.attribute ("raw", "!~"); -#if defined (DARWIN) - rhs.attribute ("raw", value); -#elif defined (SOLARIS) - rhs.attribute ("raw", "\\<" + value + "\\>"); + } else if (mod == "noword") { + op.attribute("raw", "!~"); +#if defined(DARWIN) + rhs.attribute("raw", value); +#elif defined(SOLARIS) + rhs.attribute("raw", "\\<" + value + "\\>"); #else - rhs.attribute ("raw", "\\b" + value + "\\b"); + rhs.attribute("raw", "\\b" + value + "\\b"); #endif - } - else - throw format ("Error: unrecognized attribute modifier '{1}'.", mod); + } else + throw format("Error: unrecognized attribute modifier '{1}'.", mod); - reconstructed.push_back (lhs); - reconstructed.push_back (op); + reconstructed.push_back(lhs); + reconstructed.push_back(op); // Do not modify this construct without full understanding. // Getting this wrong breaks a whole lot of filtering tests. - if (evalSupported) - { - for (auto& v : values) - reconstructed.push_back (v); - } - else if (Lexer::isDOM (rhs.attribute ("raw"))) - { + if (evalSupported) { + for (auto& v : values) reconstructed.push_back(v); + } else if (Lexer::isDOM(rhs.attribute("raw"))) { rhs._lextype = Lexer::Type::dom; - reconstructed.push_back (rhs); - } - else - { - reconstructed.push_back (rhs); + reconstructed.push_back(rhs); + } else { + reconstructed.push_back(rhs); } found = true; @@ -1496,66 +1231,58 @@ void CLI2::desugarFilterAttributes () // If the name does not canonicalize to either an attribute or a UDA // then it is not a recognized Lexer::Type::pair, so downgrade it to // Lexer::Type::word. - else - { + else { a._lextype = Lexer::Type::word; } if (found) changes = true; else - reconstructed.push_back (a); + reconstructed.push_back(a); } // Not a FILTER pair. else - reconstructed.push_back (a); + reconstructed.push_back(a); } - if (changes) - { + if (changes) { _args = reconstructed; - if (Context::getContext ().config.getInteger ("debug.parser") >= 2) - Context::getContext ().debug (dump ("CLI2::prepareFilter desugarFilterAttributes")); + if (Context::getContext().config.getInteger("debug.parser") >= 2) + Context::getContext().debug(dump("CLI2::prepareFilter desugarFilterAttributes")); } } //////////////////////////////////////////////////////////////////////////////// // /pattern/ --> description ~ 'pattern' -void CLI2::desugarFilterPatterns () -{ +void CLI2::desugarFilterPatterns() { bool changes = false; - std::vector reconstructed; - for (const auto& a : _args) - { - if (a._lextype == Lexer::Type::pattern && - a.hasTag ("FILTER")) - { + std::vector reconstructed; + for (const auto& a : _args) { + if (a._lextype == Lexer::Type::pattern && a.hasTag("FILTER")) { changes = true; - A2 lhs ("description", Lexer::Type::dom); - lhs.tag ("FILTER"); - reconstructed.push_back (lhs); + A2 lhs("description", Lexer::Type::dom); + lhs.tag("FILTER"); + reconstructed.push_back(lhs); - A2 op ("~", Lexer::Type::op); - op.tag ("FILTER"); - reconstructed.push_back (op); + A2 op("~", Lexer::Type::op); + op.tag("FILTER"); + reconstructed.push_back(op); - A2 rhs (a.attribute ("pattern"), Lexer::Type::string); - rhs.attribute ("flags", a.attribute ("flags")); - rhs.tag ("FILTER"); - reconstructed.push_back (rhs); - } - else - reconstructed.push_back (a); + A2 rhs(a.attribute("pattern"), Lexer::Type::string); + rhs.attribute("flags", a.attribute("flags")); + rhs.tag("FILTER"); + reconstructed.push_back(rhs); + } else + reconstructed.push_back(a); } - if (changes) - { + if (changes) { _args = reconstructed; - if (Context::getContext ().config.getInteger ("debug.parser") >= 2) - Context::getContext ().debug (dump ("CLI2::prepareFilter desugarFilterPatterns")); + if (Context::getContext().config.getInteger("debug.parser") >= 2) + Context::getContext().debug(dump("CLI2::prepareFilter desugarFilterPatterns")); } } @@ -1568,99 +1295,75 @@ void CLI2::desugarFilterPatterns () // a range: 5-10 // or a combination: 1,3,5-10 12 // -void CLI2::findIDs () -{ +void CLI2::findIDs() { bool changes = false; - if (Context::getContext ().config.getBoolean ("sugar")) - { + if (Context::getContext().config.getBoolean("sugar")) { bool previousFilterArgWasAnOperator = false; int filterCount = 0; - for (const auto& a : _args) - { - if (a.hasTag ("FILTER")) - { + for (const auto& a : _args) { + if (a.hasTag("FILTER")) { ++filterCount; - if (a._lextype == Lexer::Type::number) - { + if (a._lextype == Lexer::Type::number) { // Skip any number that was preceded by an operator. - if (! previousFilterArgWasAnOperator) - { + if (!previousFilterArgWasAnOperator) { changes = true; - std::string number = a.attribute ("raw"); - _id_ranges.emplace_back (number, number); + std::string number = a.attribute("raw"); + _id_ranges.emplace_back(number, number); } - } - else if (a._lextype == Lexer::Type::set) - { + } else if (a._lextype == Lexer::Type::set) { // Split the ID list into elements. - auto elements = split (a.attribute ("raw"), ','); + auto elements = split(a.attribute("raw"), ','); - for (auto& element : elements) - { + for (auto& element : elements) { changes = true; - auto hyphen = element.find ('-'); + auto hyphen = element.find('-'); if (hyphen != std::string::npos) - _id_ranges.emplace_back (element.substr (0, hyphen), element.substr (hyphen + 1)); + _id_ranges.emplace_back(element.substr(0, hyphen), element.substr(hyphen + 1)); else - _id_ranges.emplace_back (element, element); + _id_ranges.emplace_back(element, element); } } - std::string raw = a.attribute ("raw"); - previousFilterArgWasAnOperator = (a._lextype == Lexer::Type::op && - raw != "(" && - raw != ")") - ? true - : false; + std::string raw = a.attribute("raw"); + previousFilterArgWasAnOperator = + (a._lextype == Lexer::Type::op && raw != "(" && raw != ")") ? true : false; } } // If no IDs were found, and no filter was specified, look for number/set // listed as a MODIFICATION. - std::string command = getCommand (); + std::string command = getCommand(); - if (! _id_ranges.size () && - filterCount == 0 && - command != "add" && - command != "log") - { - for (auto& a : _args) - { - if (a.hasTag ("MODIFICATION")) - { - std::string raw = a.attribute ("raw"); + if (!_id_ranges.size() && filterCount == 0 && command != "add" && command != "log") { + for (auto& a : _args) { + if (a.hasTag("MODIFICATION")) { + std::string raw = a.attribute("raw"); // For a number to be an ID, it must not contain any sign or floating // point elements. - if (a._lextype == Lexer::Type::number && - raw.find ('.') == std::string::npos && - raw.find ('e') == std::string::npos && - raw.find ('-') == std::string::npos) - { + if (a._lextype == Lexer::Type::number && raw.find('.') == std::string::npos && + raw.find('e') == std::string::npos && raw.find('-') == std::string::npos) { changes = true; - a.unTag ("MODIFICATION"); - a.tag ("FILTER"); - _id_ranges.emplace_back (raw, raw); - } - else if (a._lextype == Lexer::Type::set) - { - a.unTag ("MODIFICATION"); - a.tag ("FILTER"); + a.unTag("MODIFICATION"); + a.tag("FILTER"); + _id_ranges.emplace_back(raw, raw); + } else if (a._lextype == Lexer::Type::set) { + a.unTag("MODIFICATION"); + a.tag("FILTER"); // Split the ID list into elements. - auto elements = split (raw, ','); + auto elements = split(raw, ','); - for (const auto& element : elements) - { + for (const auto& element : elements) { changes = true; - auto hyphen = element.find ('-'); + auto hyphen = element.find('-'); if (hyphen != std::string::npos) - _id_ranges.emplace_back (element.substr (0, hyphen), element.substr (hyphen + 1)); + _id_ranges.emplace_back(element.substr(0, hyphen), element.substr(hyphen + 1)); else - _id_ranges.emplace_back (element, element); + _id_ranges.emplace_back(element, element); } } } @@ -1669,117 +1372,89 @@ void CLI2::findIDs () } // Sugar-free. - else - { - std::vector reconstructed; - for (const auto& a : _args) - { - if (a.hasTag ("FILTER") && - a._lextype == Lexer::Type::number) - { + else { + std::vector reconstructed; + for (const auto& a : _args) { + if (a.hasTag("FILTER") && a._lextype == Lexer::Type::number) { changes = true; - A2 pair ("id:" + a.attribute ("raw"), Lexer::Type::pair); - pair.tag ("FILTER"); - pair.decompose (); - reconstructed.push_back (pair); - } - else - reconstructed.push_back (a); + A2 pair("id:" + a.attribute("raw"), Lexer::Type::pair); + pair.tag("FILTER"); + pair.decompose(); + reconstructed.push_back(pair); + } else + reconstructed.push_back(a); } - if (changes) - _args = reconstructed; + if (changes) _args = reconstructed; } if (changes) - if (Context::getContext ().config.getInteger ("debug.parser") >= 2) - Context::getContext ().debug (dump ("CLI2::prepareFilter findIDs")); + if (Context::getContext().config.getInteger("debug.parser") >= 2) + Context::getContext().debug(dump("CLI2::prepareFilter findIDs")); } //////////////////////////////////////////////////////////////////////////////// -void CLI2::findUUIDs () -{ +void CLI2::findUUIDs() { bool changes = false; - if (Context::getContext ().config.getBoolean ("sugar")) - { - for (const auto& a : _args) - { - if (a._lextype == Lexer::Type::uuid && - a.hasTag ("FILTER")) - { + if (Context::getContext().config.getBoolean("sugar")) { + for (const auto& a : _args) { + if (a._lextype == Lexer::Type::uuid && a.hasTag("FILTER")) { changes = true; - _uuid_list.push_back (a.attribute ("raw")); + _uuid_list.push_back(a.attribute("raw")); } } - if (! _uuid_list.size ()) - { - for (auto& a : _args) - { - if (a._lextype == Lexer::Type::uuid && - a.hasTag ("MODIFICATION")) - { + if (!_uuid_list.size()) { + for (auto& a : _args) { + if (a._lextype == Lexer::Type::uuid && a.hasTag("MODIFICATION")) { changes = true; - a.unTag ("MODIFICATION"); - a.tag ("FILTER"); - _uuid_list.push_back (a.attribute ("raw")); + a.unTag("MODIFICATION"); + a.tag("FILTER"); + _uuid_list.push_back(a.attribute("raw")); } } } } // Sugar-free. - else - { - std::vector reconstructed; - for (const auto& a : _args) - { - if (a.hasTag ("FILTER") && - a._lextype == Lexer::Type::uuid) - { + else { + std::vector reconstructed; + for (const auto& a : _args) { + if (a.hasTag("FILTER") && a._lextype == Lexer::Type::uuid) { changes = true; - A2 pair ("uuid:" + a.attribute ("raw"), Lexer::Type::pair); - pair.tag ("FILTER"); - pair.decompose (); - reconstructed.push_back (pair); - } - else - reconstructed.push_back (a); + A2 pair("uuid:" + a.attribute("raw"), Lexer::Type::pair); + pair.tag("FILTER"); + pair.decompose(); + reconstructed.push_back(pair); + } else + reconstructed.push_back(a); } - if (changes) - _args = reconstructed; + if (changes) _args = reconstructed; } if (changes) - if (Context::getContext ().config.getInteger ("debug.parser") >= 2) - Context::getContext ().debug (dump ("CLI2::prepareFilter findUUIDs")); + if (Context::getContext().config.getInteger("debug.parser") >= 2) + Context::getContext().debug(dump("CLI2::prepareFilter findUUIDs")); } //////////////////////////////////////////////////////////////////////////////// -void CLI2::insertIDExpr () -{ +void CLI2::insertIDExpr() { // Skip completely if no ID/UUID was found. This is because below, '(' and ')' // are inserted regardless of list size. - if (! _id_ranges.size () && - ! _uuid_list.size ()) - return; + if (!_id_ranges.size() && !_uuid_list.size()) return; // Find the *first* occurence of lexer type set/number/uuid, and replace it // with a synthesized expression. All other occurences are eaten. bool changes = false; bool foundID = false; - std::vector reconstructed; - for (const auto& a : _args) - { - if ((a._lextype == Lexer::Type::set || - a._lextype == Lexer::Type::number || + std::vector reconstructed; + for (const auto& a : _args) { + if ((a._lextype == Lexer::Type::set || a._lextype == Lexer::Type::number || a._lextype == Lexer::Type::uuid) && - a.hasTag ("FILTER")) - { - if (! foundID) - { + a.hasTag("FILTER")) { + if (!foundID) { foundID = true; changes = true; @@ -1799,146 +1474,136 @@ void CLI2::insertIDExpr () // ) // Building block operators. - A2 openParen ("(", Lexer::Type::op); openParen.tag ("FILTER"); - A2 closeParen (")", Lexer::Type::op); closeParen.tag ("FILTER"); - A2 opOr ("or", Lexer::Type::op); opOr.tag ("FILTER"); - A2 opAnd ("and", Lexer::Type::op); opAnd.tag ("FILTER"); - A2 opSimilar ("=", Lexer::Type::op); opSimilar.tag ("FILTER"); - A2 opEqual ("==", Lexer::Type::op); opEqual.tag ("FILTER"); - A2 opGTE (">=", Lexer::Type::op); opGTE.tag ("FILTER"); - A2 opLTE ("<=", Lexer::Type::op); opLTE.tag ("FILTER"); + A2 openParen("(", Lexer::Type::op); + openParen.tag("FILTER"); + A2 closeParen(")", Lexer::Type::op); + closeParen.tag("FILTER"); + A2 opOr("or", Lexer::Type::op); + opOr.tag("FILTER"); + A2 opAnd("and", Lexer::Type::op); + opAnd.tag("FILTER"); + A2 opSimilar("=", Lexer::Type::op); + opSimilar.tag("FILTER"); + A2 opEqual("==", Lexer::Type::op); + opEqual.tag("FILTER"); + A2 opGTE(">=", Lexer::Type::op); + opGTE.tag("FILTER"); + A2 opLTE("<=", Lexer::Type::op); + opLTE.tag("FILTER"); // Building block attributes. - A2 argID ("id", Lexer::Type::dom); - argID.tag ("FILTER"); + A2 argID("id", Lexer::Type::dom); + argID.tag("FILTER"); - A2 argUUID ("uuid", Lexer::Type::dom); - argUUID.tag ("FILTER"); + A2 argUUID("uuid", Lexer::Type::dom); + argUUID.tag("FILTER"); - reconstructed.push_back (openParen); + reconstructed.push_back(openParen); // Add all ID ranges. - for (auto r = _id_ranges.begin (); r != _id_ranges.end (); ++r) - { - if (r != _id_ranges.begin ()) - reconstructed.push_back (opOr); + for (auto r = _id_ranges.begin(); r != _id_ranges.end(); ++r) { + if (r != _id_ranges.begin()) reconstructed.push_back(opOr); - if (r->first == r->second) - { - reconstructed.push_back (openParen); - reconstructed.push_back (argID); - reconstructed.push_back (opEqual); + if (r->first == r->second) { + reconstructed.push_back(openParen); + reconstructed.push_back(argID); + reconstructed.push_back(opEqual); - A2 value (r->first, Lexer::Type::number); - value.tag ("FILTER"); - reconstructed.push_back (value); + A2 value(r->first, Lexer::Type::number); + value.tag("FILTER"); + reconstructed.push_back(value); - reconstructed.push_back (closeParen); - } - else - { + reconstructed.push_back(closeParen); + } else { bool ascending = true; - int low = strtol (r->first.c_str (), nullptr, 10); - int high = strtol (r->second.c_str (), nullptr, 10); + int low = strtol(r->first.c_str(), nullptr, 10); + int high = strtol(r->second.c_str(), nullptr, 10); if (low <= high) ascending = true; else ascending = false; - reconstructed.push_back (openParen); - reconstructed.push_back (argID); - reconstructed.push_back (opGTE); + reconstructed.push_back(openParen); + reconstructed.push_back(argID); + reconstructed.push_back(opGTE); - A2 startValue ((ascending ? r->first : r->second), Lexer::Type::number); - startValue.tag ("FILTER"); - reconstructed.push_back (startValue); + A2 startValue((ascending ? r->first : r->second), Lexer::Type::number); + startValue.tag("FILTER"); + reconstructed.push_back(startValue); - reconstructed.push_back (opAnd); - reconstructed.push_back (argID); - reconstructed.push_back (opLTE); + reconstructed.push_back(opAnd); + reconstructed.push_back(argID); + reconstructed.push_back(opLTE); - A2 endValue ((ascending ? r->second : r->first), Lexer::Type::number); - endValue.tag ("FILTER"); - reconstructed.push_back (endValue); + A2 endValue((ascending ? r->second : r->first), Lexer::Type::number); + endValue.tag("FILTER"); + reconstructed.push_back(endValue); - reconstructed.push_back (closeParen); + reconstructed.push_back(closeParen); } } // Combine the ID and UUID sections with 'or'. - if (_id_ranges.size () && - _uuid_list.size ()) - reconstructed.push_back (opOr); + if (_id_ranges.size() && _uuid_list.size()) reconstructed.push_back(opOr); // Add all UUID list items. - for (auto u = _uuid_list.begin (); u != _uuid_list.end (); ++u) - { - if (u != _uuid_list.begin ()) - reconstructed.push_back (opOr); + for (auto u = _uuid_list.begin(); u != _uuid_list.end(); ++u) { + if (u != _uuid_list.begin()) reconstructed.push_back(opOr); - reconstructed.push_back (openParen); - reconstructed.push_back (argUUID); - reconstructed.push_back (opSimilar); + reconstructed.push_back(openParen); + reconstructed.push_back(argUUID); + reconstructed.push_back(opSimilar); - A2 value (*u, Lexer::Type::string); - value.tag ("FILTER"); - reconstructed.push_back (value); + A2 value(*u, Lexer::Type::string); + value.tag("FILTER"); + reconstructed.push_back(value); - reconstructed.push_back (closeParen); + reconstructed.push_back(closeParen); } - reconstructed.push_back (closeParen); + reconstructed.push_back(closeParen); } // No 'else' because all set/number/uuid args but the first are removed. - } - else - reconstructed.push_back (a); + } else + reconstructed.push_back(a); } - if (changes) - { + if (changes) { _args = reconstructed; - if (Context::getContext ().config.getInteger ("debug.parser") >= 2) - Context::getContext ().debug (dump ("CLI2::prepareFilter insertIDExpr")); + if (Context::getContext().config.getInteger("debug.parser") >= 2) + Context::getContext().debug(dump("CLI2::prepareFilter insertIDExpr")); } } //////////////////////////////////////////////////////////////////////////////// // FILTER Lexer::Type::word args will become part of an expression, and so they // need to be Lexed. -void CLI2::lexFilterArgs () -{ +void CLI2::lexFilterArgs() { bool changes = false; - std::vector reconstructed; - for (const auto& a : _args) - { - if (a._lextype == Lexer::Type::word && - a.hasTag ("FILTER")) - { + std::vector reconstructed; + for (const auto& a : _args) { + if (a._lextype == Lexer::Type::word && a.hasTag("FILTER")) { changes = true; std::string lexeme; Lexer::Type type; - Lexer lex (a.attribute ("raw")); - while (lex.token (lexeme, type)) - { - A2 extra (lexeme, type); - extra.tag ("FILTER"); - reconstructed.push_back (extra); + Lexer lex(a.attribute("raw")); + while (lex.token(lexeme, type)) { + A2 extra(lexeme, type); + extra.tag("FILTER"); + reconstructed.push_back(extra); } - } - else - reconstructed.push_back (a); + } else + reconstructed.push_back(a); } - if (changes) - { + if (changes) { _args = reconstructed; - if (Context::getContext ().config.getInteger ("debug.parser") >= 2) - Context::getContext ().debug (dump ("CLI2::prepareFilter lexFilterArgs")); + if (Context::getContext().config.getInteger("debug.parser") >= 2) + Context::getContext().debug(dump("CLI2::prepareFilter lexFilterArgs")); } } @@ -1954,39 +1619,28 @@ void CLI2::lexFilterArgs () // Lexer::Type::identifier // Lexer::Type::date // -void CLI2::desugarFilterPlainArgs () -{ +void CLI2::desugarFilterPlainArgs() { // First walk the arg list looking for plain words that are not part of an // existing expression. auto prevprev = &_args[0]; auto prev = &_args[0]; - for (auto& a : _args) - { - auto raw = a.attribute ("raw"); - auto praw = prev->attribute ("raw"); - auto ppraw = prevprev->attribute ("raw"); + for (auto& a : _args) { + auto raw = a.attribute("raw"); + auto praw = prev->attribute("raw"); + auto ppraw = prevprev->attribute("raw"); - if ((prevprev->_lextype != Lexer::Type::op || // argX - ppraw == "(" || - ppraw == ")" || - ppraw == "and" || - ppraw == "or" || - ppraw == "xor") && + if ((prevprev->_lextype != Lexer::Type::op || // argX + ppraw == "(" || ppraw == ")" || ppraw == "and" || ppraw == "or" || ppraw == "xor") && (prev->_lextype == Lexer::Type::identifier || // candidate - prev->_lextype == Lexer::Type::date || // candidate - prev->_lextype == Lexer::Type::word) && // candidate + prev->_lextype == Lexer::Type::date || // candidate + prev->_lextype == Lexer::Type::word) && // candidate - prev->hasTag ("FILTER") && // candidate + prev->hasTag("FILTER") && // candidate - (a._lextype != Lexer::Type::op || // argY - raw == "(" || - raw == ")" || - raw == "and" || - raw == "or" || - raw == "xor")) - { - prev->tag ("PLAIN"); + (a._lextype != Lexer::Type::op || // argY + raw == "(" || raw == ")" || raw == "and" || raw == "or" || raw == "xor")) { + prev->tag("PLAIN"); } prevprev = prev; @@ -1994,61 +1648,53 @@ void CLI2::desugarFilterPlainArgs () } // Cover the case where the *last* argument is a plain arg. - auto& penultimate = _args[_args.size () - 2]; - auto praw = penultimate.attribute ("raw"); - auto& last = _args[_args.size () - 1]; - if ((penultimate._lextype != Lexer::Type::op || // argX - praw == "(" || - praw == ")" || - praw == "and" || - praw == "or" || - praw == "xor") && + auto& penultimate = _args[_args.size() - 2]; + auto praw = penultimate.attribute("raw"); + auto& last = _args[_args.size() - 1]; + if ((penultimate._lextype != Lexer::Type::op || // argX + praw == "(" || praw == ")" || praw == "and" || praw == "or" || praw == "xor") && - (last._lextype == Lexer::Type::identifier || // candidate - last._lextype == Lexer::Type::word) && // candidate + (last._lextype == Lexer::Type::identifier || // candidate + last._lextype == Lexer::Type::word) && // candidate - last.hasTag ("FILTER")) // candidate + last.hasTag("FILTER")) // candidate { - last.tag ("PLAIN"); + last.tag("PLAIN"); } // Walk the list again, upgrading PLAIN args. bool changes = false; - std::vector reconstructed; - for (const auto& a : _args) - { - if (a.hasTag ("PLAIN")) - { + std::vector reconstructed; + for (const auto& a : _args) { + if (a.hasTag("PLAIN")) { changes = true; - A2 lhs ("description", Lexer::Type::dom); - lhs.attribute ("canonical", "description"); - lhs.tag ("FILTER"); - lhs.tag ("PLAIN"); - reconstructed.push_back (lhs); + A2 lhs("description", Lexer::Type::dom); + lhs.attribute("canonical", "description"); + lhs.tag("FILTER"); + lhs.tag("PLAIN"); + reconstructed.push_back(lhs); - A2 op ("~", Lexer::Type::op); - op.tag ("FILTER"); - op.tag ("PLAIN"); - reconstructed.push_back (op); + A2 op("~", Lexer::Type::op); + op.tag("FILTER"); + op.tag("PLAIN"); + reconstructed.push_back(op); - std::string word = a.attribute ("raw"); - Lexer::dequote (word); - A2 rhs (word, Lexer::Type::string); - rhs.tag ("FILTER"); - rhs.tag ("PLAIN"); - reconstructed.push_back (rhs); - } - else - reconstructed.push_back (a); + std::string word = a.attribute("raw"); + Lexer::dequote(word); + A2 rhs(word, Lexer::Type::string); + rhs.tag("FILTER"); + rhs.tag("PLAIN"); + reconstructed.push_back(rhs); + } else + reconstructed.push_back(a); } - if (changes) - { + if (changes) { _args = reconstructed; - if (Context::getContext ().config.getInteger ("debug.parser") >= 2) - Context::getContext ().debug (dump ("CLI2::prepareFilter desugarFilterPlainArgs")); + if (Context::getContext().config.getInteger("debug.parser") >= 2) + Context::getContext().debug(dump("CLI2::prepareFilter desugarFilterPlainArgs")); } } @@ -2062,13 +1708,11 @@ void CLI2::desugarFilterPlainArgs () // ( status = pending ) ( project = Home ) // ^ // it -----| => false -bool CLI2::isEmptyParenExpression (std::vector::iterator it, bool forward /* = true */) const -{ +bool CLI2::isEmptyParenExpression(std::vector::iterator it, bool forward /* = true */) const { int open = 0; int closed = 0; - for (auto a = it; a != (forward ? _args.end (): _args.begin()); (forward ? ++a: --a)) - { + for (auto a = it; a != (forward ? _args.end() : _args.begin()); (forward ? ++a : --a)) { if (a->attribute("raw") == "(") open++; else if (a->attribute("raw") == ")") @@ -2078,8 +1722,7 @@ bool CLI2::isEmptyParenExpression (std::vector::iterator it, bool forward /* return false; // Getting balanced parentheses means we have an empty paren expression - if (open == closed && open != 0) - return true; + if (open == closed && open != 0) return true; } // Should not end here. @@ -2095,39 +1738,28 @@ bool CLI2::isEmptyParenExpression (std::vector::iterator it, bool forward /* // ) ( --> ) and ( // --> and // -void CLI2::insertJunctions () -{ +void CLI2::insertJunctions() { bool changes = false; - std::vector reconstructed; - auto prev = _args.begin (); + std::vector reconstructed; + auto prev = _args.begin(); - for (auto a = _args.begin (); a != _args.end (); ++a) - { - if (a->hasTag ("FILTER")) - { + for (auto a = _args.begin(); a != _args.end(); ++a) { + if (a->hasTag("FILTER")) { // The prev iterator should be the first FILTER arg. - if (prev == _args.begin ()) - prev = a; + if (prev == _args.begin()) prev = a; // Insert AND between terms. - else if (a != prev) - { - if ((prev->_lextype != Lexer::Type::op && - a->attribute ("raw") == "(" && - ! isEmptyParenExpression(a, true) ) || - (prev->attribute ("raw") == ")" && - a->_lextype != Lexer::Type::op && - ! isEmptyParenExpression(prev, false)) || - (prev->attribute ("raw") == ")" && - a->attribute ("raw") == "(" && - ! isEmptyParenExpression(a, true) && - ! isEmptyParenExpression(prev, false)) || - (prev->_lextype != Lexer::Type::op && - a->_lextype != Lexer::Type::op)) - { - A2 opOr ("and", Lexer::Type::op); - opOr.tag ("FILTER"); - reconstructed.push_back (opOr); + else if (a != prev) { + if ((prev->_lextype != Lexer::Type::op && a->attribute("raw") == "(" && + !isEmptyParenExpression(a, true)) || + (prev->attribute("raw") == ")" && a->_lextype != Lexer::Type::op && + !isEmptyParenExpression(prev, false)) || + (prev->attribute("raw") == ")" && a->attribute("raw") == "(" && + !isEmptyParenExpression(a, true) && !isEmptyParenExpression(prev, false)) || + (prev->_lextype != Lexer::Type::op && a->_lextype != Lexer::Type::op)) { + A2 opOr("and", Lexer::Type::op); + opOr.tag("FILTER"); + reconstructed.push_back(opOr); changes = true; } } @@ -2136,15 +1768,14 @@ void CLI2::insertJunctions () prev = a; } - reconstructed.push_back (*a); + reconstructed.push_back(*a); } - if (changes) - { + if (changes) { _args = reconstructed; - if (Context::getContext ().config.getInteger ("debug.parser") >= 2) - Context::getContext ().debug (dump ("CLI2::prepareFilter insertJunctions")); + if (Context::getContext().config.getInteger("debug.parser") >= 2) + Context::getContext().debug(dump("CLI2::prepareFilter insertJunctions")); } } @@ -2157,78 +1788,65 @@ void CLI2::insertJunctions () // 2. If no command was found, but an ID/UUID was found, then assume a command // of 'information'. // -void CLI2::defaultCommand () -{ +void CLI2::defaultCommand() { // Scan the top-level branches for evidence of ID, UUID, overrides and other // arguments. - bool changes = false; - bool found_command = false; - bool found_sequence = false; + bool changes = false; + bool found_command = false; + bool found_sequence = false; - for (const auto& a : _args) - { - std::string raw = a.attribute ("raw"); + for (const auto& a : _args) { + std::string raw = a.attribute("raw"); - if (a.hasTag ("CMD")) - found_command = true; + if (a.hasTag("CMD")) found_command = true; - if (a._lextype == Lexer::Type::uuid || - a._lextype == Lexer::Type::number) - found_sequence = true; + if (a._lextype == Lexer::Type::uuid || a._lextype == Lexer::Type::number) found_sequence = true; } // If no command was specified, then a command will be inserted. - if (! found_command) - { + if (!found_command) { // Default command. - if (! found_sequence) - { + if (!found_sequence) { // Apply overrides, if any. - std::string defaultCommand = Context::getContext ().config.get ("default.command"); - if (defaultCommand != "") - { + std::string defaultCommand = Context::getContext().config.get("default.command"); + if (defaultCommand != "") { // Modify _args, _original_args to be: // [ ...] [...] - std::vector reconstructedOriginals {_original_args[0]}; - std::vector reconstructed {_args[0]}; + std::vector reconstructedOriginals{_original_args[0]}; + std::vector reconstructed{_args[0]}; std::string lexeme; Lexer::Type type; - Lexer lex (defaultCommand); + Lexer lex(defaultCommand); - while (lex.token (lexeme, type)) - { - reconstructedOriginals.emplace_back (lexeme, type); + while (lex.token(lexeme, type)) { + reconstructedOriginals.emplace_back(lexeme, type); - A2 cmd (lexeme, type); - cmd.tag ("DEFAULT"); - reconstructed.push_back (cmd); + A2 cmd(lexeme, type); + cmd.tag("DEFAULT"); + reconstructed.push_back(cmd); } - for (unsigned int i = 1; i < _original_args.size (); ++i) - reconstructedOriginals.push_back (_original_args[i]); + for (unsigned int i = 1; i < _original_args.size(); ++i) + reconstructedOriginals.push_back(_original_args[i]); - for (unsigned int i = 1; i < _args.size (); ++i) - reconstructed.push_back (_args[i]); + for (unsigned int i = 1; i < _args.size(); ++i) reconstructed.push_back(_args[i]); _original_args = reconstructedOriginals; _args = reconstructed; changes = true; } - } - else - { - A2 info ("information", Lexer::Type::word); - info.tag ("ASSUMED"); - _args.push_back (info); + } else { + A2 info("information", Lexer::Type::word); + info.tag("ASSUMED"); + _args.push_back(info); changes = true; } } - if (changes && - Context::getContext ().config.getInteger ("debug.parser") >= 2) - Context::getContext ().debug (dump ("CLI2::analyze defaultCommand")); + if (changes && Context::getContext().config.getInteger("debug.parser") >= 2) + Context::getContext().debug(dump("CLI2::analyze defaultCommand")); } //////////////////////////////////////////////////////////////////////////////// @@ -2242,30 +1860,27 @@ void CLI2::defaultCommand () // + // 1d // ) -std::vector CLI2::lexExpression (const std::string& expression) -{ - std::vector lexed; +std::vector CLI2::lexExpression(const std::string& expression) { + std::vector lexed; std::string lexeme; Lexer::Type type; - Lexer lex (expression); - while (lex.token (lexeme, type)) - { - A2 token (lexeme, type); - token.tag ("FILTER"); - lexed.push_back (token); + Lexer lex(expression); + while (lex.token(lexeme, type)) { + A2 token(lexeme, type); + token.tag("FILTER"); + lexed.push_back(token); } // If there were multiple tokens, parenthesize, because this expression will // be used as a value. - if (lexed.size () > 1) - { - A2 openParen ("(", Lexer::Type::op); - openParen.tag ("FILTER"); - A2 closeParen (")", Lexer::Type::op); - closeParen.tag ("FILTER"); + if (lexed.size() > 1) { + A2 openParen("(", Lexer::Type::op); + openParen.tag("FILTER"); + A2 closeParen(")", Lexer::Type::op); + closeParen.tag("FILTER"); - lexed.insert (lexed.begin (), openParen); - lexed.push_back (closeParen); + lexed.insert(lexed.begin(), openParen); + lexed.push_back(closeParen); } return lexed; diff --git a/src/CLI2.h b/src/CLI2.h index 6bada618a..ec446d688 100644 --- a/src/CLI2.h +++ b/src/CLI2.h @@ -26,100 +26,98 @@ #ifndef INCLUDED_CLI2 #define INCLUDED_CLI2 -#include -#include -#include -#include -#include #include +#include + +#include +#include +#include +#include // Represents a single argument. -class A2 -{ -public: - A2 (const std::string&, Lexer::Type); - A2 (const A2&); - A2& operator= (const A2&); - bool hasTag (const std::string&) const; - void tag (const std::string&); - void unTag (const std::string&); - void attribute (const std::string&, const std::string&); - const std::string attribute (const std::string&) const; - const std::string getToken () const; - const std::string dump () const; - void decompose (); +class A2 { + public: + A2(const std::string&, Lexer::Type); + A2(const A2&); + A2& operator=(const A2&); + bool hasTag(const std::string&) const; + void tag(const std::string&); + void unTag(const std::string&); + void attribute(const std::string&, const std::string&); + const std::string attribute(const std::string&) const; + const std::string getToken() const; + const std::string dump() const; + void decompose(); -public: - Lexer::Type _lextype {Lexer::Type::word}; - std::vector _tags {}; - std::map _attributes {}; + public: + Lexer::Type _lextype{Lexer::Type::word}; + std::vector _tags{}; + std::map _attributes{}; }; // Represents the command line. -class CLI2 -{ -public: +class CLI2 { + public: static int minimumMatchLength; - static bool getOverride (int, const char**, File&); - static bool getDataLocation (int, const char**, Path&); - static void applyOverrides (int, const char**); + static bool getOverride(int, const char**, File&); + static bool getDataLocation(int, const char**, Path&); + static void applyOverrides(int, const char**); -public: - CLI2 () = default; - void alias (const std::string&, const std::string&); - void entity (const std::string&, const std::string&); + public: + CLI2() = default; + void alias(const std::string&, const std::string&); + void entity(const std::string&, const std::string&); - void add (const std::string&); - void add (const std::vector &, int offset = 0); - void analyze (); - void addFilter (const std::string& arg); - void addModifications (const std::string& arg); - void addContext (bool readable, bool writeable); - void prepareFilter (); - const std::vector getWords (); - const std::vector getMiscellaneous (); - bool canonicalize (std::string&, const std::string&, const std::string&); - std::string getBinary () const; - std::string getCommand (bool canonical = true) const; - const std::string dump (const std::string& title = "CLI2 Parser") const; + void add(const std::string&); + void add(const std::vector&, int offset = 0); + void analyze(); + void addFilter(const std::string& arg); + void addModifications(const std::string& arg); + void addContext(bool readable, bool writeable); + void prepareFilter(); + const std::vector getWords(); + const std::vector getMiscellaneous(); + bool canonicalize(std::string&, const std::string&, const std::string&); + std::string getBinary() const; + std::string getCommand(bool canonical = true) const; + const std::string dump(const std::string& title = "CLI2 Parser") const; -private: - void handleArg0 (); - void lexArguments (); - void demotion (); - void aliasExpansion (); - void canonicalizeNames (); - void categorizeArgs (); - void parenthesizeOriginalFilter (); - bool findCommand (); - bool exactMatch (const std::string&, const std::string&) const; - void desugarFilterTags (); - void findStrayModifications (); - void desugarFilterAttributes (); - void desugarFilterPatterns (); - void findIDs (); - void findUUIDs (); - void insertIDExpr (); - void lexFilterArgs (); - bool isEmptyParenExpression (std::vector::iterator it, bool forward = true) const; - void desugarFilterPlainArgs (); - void insertJunctions (); - void defaultCommand (); - std::vector lexExpression (const std::string&); + private: + void handleArg0(); + void lexArguments(); + void demotion(); + void aliasExpansion(); + void canonicalizeNames(); + void categorizeArgs(); + void parenthesizeOriginalFilter(); + bool findCommand(); + bool exactMatch(const std::string&, const std::string&) const; + void desugarFilterTags(); + void findStrayModifications(); + void desugarFilterAttributes(); + void desugarFilterPatterns(); + void findIDs(); + void findUUIDs(); + void insertIDExpr(); + void lexFilterArgs(); + bool isEmptyParenExpression(std::vector::iterator it, bool forward = true) const; + void desugarFilterPlainArgs(); + void insertJunctions(); + void defaultCommand(); + std::vector lexExpression(const std::string&); -public: - std::multimap _entities {}; - std::map _aliases {}; - std::unordered_map _canonical_cache {}; - std::vector _original_args {}; - std::vector _args {}; + public: + std::multimap _entities{}; + std::map _aliases{}; + std::unordered_map _canonical_cache{}; + std::vector _original_args{}; + std::vector _args{}; - std::vector > _id_ranges {}; - std::vector _uuid_list {}; - std::string _command {""}; - bool _context_added {false}; + std::vector> _id_ranges{}; + std::vector _uuid_list{}; + std::string _command{""}; + bool _context_added{false}; }; #endif - diff --git a/src/Context.cpp b/src/Context.cpp index 2004d26ce..363c1d640 100644 --- a/src/Context.cpp +++ b/src/Context.cpp @@ -28,25 +28,26 @@ // cmake.h include header must come first #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include #include +#include +#include +#include #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include + +#include +#include +#include +#include #include +#include #ifdef HAVE_COMMIT #include @@ -61,418 +62,451 @@ //////////////////////////////////////////////////////////////////////////////// // This string is parsed and used as default values for configuration. -// Note: New configuration options should be added to the vim syntax file in scripts/vim/syntax/taskrc.vim +// Note: New configuration options should be added to the vim syntax file in +// scripts/vim/syntax/taskrc.vim std::string configurationDefaults = - "# Taskwarrior program configuration file.\n" - "# For more documentation, see https://taskwarrior.org or try 'man task', 'man task-color',\n" - "# 'man task-sync' or 'man taskrc'\n" - "\n" - "# Here is an example of entries that use the default, override and blank values\n" - "# variable=foo -- By specifying a value, this overrides the default\n" - "# variable= -- By specifying no value, this means no default\n" - "# #variable=foo -- By commenting out the line, or deleting it, this uses the default\n" - "\n" - "# You can also refence environment variables:\n" - "# variable=$HOME/task\n" - "# variable=$VALUE\n" - "\n" - "# Use the command 'task show' to see all defaults and overrides\n" - "\n" - "# Files\n" - "data.location=~/.task\n" - "gc=1 # Garbage-collect data files - DO NOT CHANGE unless you are sure\n" - "exit.on.missing.db=0 # Whether to exit if ~/.task is not found\n" - "hooks=1 # Master control switch for hooks\n" - "\n" - "# Terminal\n" - "detection=1 # Detects terminal width\n" - "defaultwidth=80 # Without detection, assumed width\n" - "defaultheight=24 # Without detection, assumed height\n" - "avoidlastcolumn=0 # Fixes Cygwin width problem\n" - "hyphenate=1 # Hyphenates lines wrapped on non-word-breaks\n" - "#editor=vi # Preferred text editor\n" - "reserved.lines=1 # Assume a 1-line prompt\n" - "\n" - "# Miscellaneous\n" - "# verbose= # Comma-separated list. May contain any subset of:\n" - "# affected,blank,context,default,edit,filter,footnote,header,label,new-id,new-uuid,news,override,project,recur,special,sync\n" - "verbose=affected,blank,context,edit,header,footnote,label,new-id,news,project,special,sync,override,recur\n" - "confirmation=1 # Confirmation on delete, big changes\n" - "recurrence=1 # Enable recurrence\n" - "recurrence.confirmation=prompt # Confirmation for propagating changes among recurring tasks (yes/no/prompt)\n" - "allow.empty.filter=1 # An empty filter gets a warning and requires confirmation\n" - "indent.annotation=2 # Indent spaces for annotations\n" - "indent.report=0 # Indent spaces for whole report\n" - "row.padding=0 # Left and right padding for each row of report\n" - "column.padding=1 # Spaces between each column in a report\n" - "bulk=3 # 3 or more tasks considered a bulk change and is confirmed\n" - "nag=You have more urgent tasks. # Nag message to keep you honest\n" // TODO - "search.case.sensitive=1 # Setting to no allows case insensitive searches\n" - "active.indicator=* # What to show as an active task indicator\n" - "tag.indicator=+ # What to show as a tag indicator\n" - "dependency.indicator=D # What to show as a dependency indicator\n" - "recurrence.indicator=R # What to show as a task recurrence indicator\n" - "recurrence.limit=1 # Number of future recurring pending tasks\n" - "undo.style=side # Undo style - can be 'side', or 'diff'\n" - "regex=1 # Assume all search/filter strings are regexes\n" - "xterm.title=0 # Sets xterm title for some commands\n" - "expressions=infix # Prefer infix over postfix expressions\n" - "json.array=1 # Enclose JSON output in [ ]\n" - "abbreviation.minimum=2 # Shortest allowed abbreviation\n" - "news.version= # Latest version highlights read by the user\n" - "purge.on-sync=0 # Purge old tasks on sync\n" - "\n" - "# Dates\n" - "dateformat=Y-M-D # Preferred input and display date format\n" - "dateformat.holiday=YMD # Preferred input date format for holidays\n" - "dateformat.edit=Y-M-D H:N:S # Preferred display date format when editing\n" - "dateformat.info=Y-M-D H:N:S # Preferred display date format for information\n" - "dateformat.report= # Preferred display date format for reports\n" - "dateformat.annotation= # Preferred display date format for annotations\n" - "date.iso=1 # Enable ISO date support\n" - "weekstart=sunday # Sunday or Monday only\n" - "displayweeknumber=1 # Show week numbers on calendar\n" - "due=7 # Task is considered due in 7 days\n" - "\n" - "# Calendar controls\n" - "calendar.legend=1 # Display the legend on calendar\n" - "calendar.details=sparse # Calendar shows information for tasks w/due dates: full, sparse or none\n" - "calendar.details.report=list # Report to use when showing task information in cal\n" - "calendar.offset=0 # Apply an offset value to control the first month of the calendar\n" - "calendar.offset.value=-1 # The number of months the first month of the calendar is moved\n" - "calendar.holidays=none # Show public holidays on calendar:full, sparse or none\n" - "#calendar.monthsperline=3 # Number of calendar months on a line\n" - "\n" - "# Journal controls\n" - "journal.time=0 # Record start/stop commands as annotation\n" - "journal.time.start.annotation=Started task # Annotation description for the start journal entry\n" - "journal.time.stop.annotation=Stopped task # Annotation description for the stop journal entry\n" - "journal.info=1 # Display task journal with info command\n" - "\n" - "# Dependency controls\n" - "dependency.reminder=1 # Nags on dependency chain violations\n" - "dependency.confirmation=1 # Should dependency chain repair be confirmed?\n" - "\n" - "# Urgency Coefficients\n" - "urgency.user.tag.next.coefficient=15.0 # Urgency coefficient for 'next' special tag\n" - "urgency.due.coefficient=12.0 # Urgency coefficient for due dates\n" - "urgency.blocking.coefficient=8.0 # Urgency coefficient for blocking tasks\n" - "urgency.active.coefficient=4.0 # Urgency coefficient for active tasks\n" - "urgency.scheduled.coefficient=5.0 # Urgency coefficient for scheduled tasks\n" - "urgency.age.coefficient=2.0 # Urgency coefficient for age\n" - "urgency.annotations.coefficient=1.0 # Urgency coefficient for annotations\n" - "urgency.tags.coefficient=1.0 # Urgency coefficient for tags\n" - "urgency.project.coefficient=1.0 # Urgency coefficient for projects\n" - "urgency.blocked.coefficient=-5.0 # Urgency coefficient for blocked tasks\n" - "urgency.waiting.coefficient=-3.0 # Urgency coefficient for waiting status\n" - "urgency.inherit=0 # Recursively inherit highest urgency value from blocked tasks\n" - "urgency.age.max=365 # Maximum age in days\n" - "\n" - "#urgency.user.project.foo.coefficient=5.0 # Urgency coefficients for 'foo' project\n" - "#urgency.user.tag.foo.coefficient=5.0 # Urgency coefficients for 'foo' tag\n" - "#urgency.uda.foo.coefficient=5.0 # Urgency coefficients for UDA 'foo'\n" - "\n" - "# Color controls.\n" - "color=1 # Enable color\n" - "\n" - "# Here is the rule precedence order, highest to lowest.\n" - "# Note that these are just the color rule names, without the leading 'color.'\n" - "# and any trailing '.value'.\n" - "rule.precedence.color=deleted,completed,active,keyword.,tag.,project.,overdue,scheduled,due.today,due,blocked,blocking,recurring,tagged,uda.\n" - "\n" - "# General decoration\n" - "rule.color.merge=1\n" - "color.label=\n" - "color.label.sort=\n" - "color.alternate=on gray2\n" - "color.header=color3\n" - "color.footnote=color3\n" - "color.warning=bold red\n" - "color.error=white on red\n" - "color.debug=color4\n" - "\n" - "# Task state\n" - "color.completed=\n" - "color.deleted=\n" - "color.active=rgb555 on rgb410\n" - "color.recurring=rgb013\n" - "color.scheduled=on rgb001\n" - "color.until=\n" - "color.blocked=white on color8\n" - "color.blocking=black on color15\n" - "\n" - "# Project\n" - "color.project.none=\n" - "\n" - "# Priority UDA\n" - "color.uda.priority.H=color255\n" - "color.uda.priority.L=color245\n" - "color.uda.priority.M=color250\n" - "\n" - "# Tags\n" - "color.tag.next=rgb440\n" - "color.tag.none=\n" - "color.tagged=rgb031\n" - "\n" - "# Due\n" - "color.due.today=rgb400\n" - "color.due=color1\n" - "color.overdue=color9\n" - "\n" - "# Report: burndown\n" - "color.burndown.done=on rgb010\n" - "color.burndown.pending=on color9\n" - "color.burndown.started=on color11\n" - "\n" - "# Report: history\n" - "color.history.add=color0 on rgb500\n" - "color.history.delete=color0 on rgb550\n" - "color.history.done=color0 on rgb050\n" - "\n" - "# Report: summary\n" - "color.summary.background=white on color0\n" - "color.summary.bar=black on rgb141\n" - "\n" - "# Command: calendar\n" - "color.calendar.due.today=color15 on color1\n" - "color.calendar.due=color0 on color1\n" - "color.calendar.holiday=color0 on color11\n" - "color.calendar.scheduled=rgb013 on color15\n" - "color.calendar.overdue=color0 on color9\n" - "color.calendar.today=color15 on rgb013\n" - "color.calendar.weekend=on color235\n" - "color.calendar.weeknumber=rgb013\n" - "\n" - "# Command: sync\n" - "color.sync.added=rgb010\n" - "color.sync.changed=color11\n" - "color.sync.rejected=color9\n" - "\n" - "# Command: undo\n" - "color.undo.after=color2\n" - "color.undo.before=color1\n" - "\n" - "# UDA priority\n" - "uda.priority.type=string # UDA priority is a string type\n" - "uda.priority.label=Priority # UDA priority has a display label'\n" - "uda.priority.values=H,M,L, # UDA priority values are 'H', 'M', 'L' or ''\n" - " # UDA priority sorting is 'H' > 'M' > 'L' > '' (highest to lowest)\n" - "#uda.priority.default=M # UDA priority default value of 'M'\n" - "urgency.uda.priority.H.coefficient=6.0 # UDA priority coefficient for value 'H'\n" - "urgency.uda.priority.M.coefficient=3.9 # UDA priority coefficient for value 'M'\n" - "urgency.uda.priority.L.coefficient=1.8 # UDA priority coefficient for value 'L'\n" - "\n" - "#default.project=foo # Default project for 'add' command\n" - "#default.due=eom # Default due date for 'add' command\n" - "#default.scheduled=eom # Default scheduled date for 'add' command\n" - "default.command=next # When no arguments are specified\n" - "default.timesheet.filter=( +PENDING and start.after:now-4wks ) or ( +COMPLETED and end.after:now-4wks )\n" - "\n" - "_forcecolor=0 # Forces color to be on, even for non TTY output\n" - "complete.all.tags=0 # Include old tag names in '_ags' command\n" - "list.all.projects=0 # Include old project names in 'projects' command\n" - "summary.all.projects=0 # Include old project names in 'summary' command\n" - "list.all.tags=0 # Include old tag names in 'tags' command\n" - "print.empty.columns=0 # Print columns which have no data for any task\n" - "debug=0 # Display diagnostics\n" - "sugar=1 # Syntactic sugar\n" - "obfuscate=0 # Obfuscate data for error reporting\n" - "fontunderline=1 # Uses underlines rather than -------\n" - "\n" - "# WARNING: Please read the documentation (man task-sync) before setting up\n" - "# Taskwarrior for Taskserver synchronization.\n" - "\n" - "#sync.encryption_secret # Encryption secret for sync to a server\n" - "#sync.server.client_id # Client ID for sync to a server\n" - "#sync.server.url # URL of the sync server\n" - "#sync.local.server_dir # Directory for local sync\n" - "#sync.gcp.credential_path # Path to JSON file containing credentials to authenticate GCP Sync\n" - "#sync.gcp.bucket # Bucket for sync to GCP\n" - "\n" - "# Aliases - alternate names for commands\n" - "alias.rm=delete # Alias for the delete command\n" - "alias.history=history.monthly # Prefer monthly over annual history reports\n" - "alias.ghistory=ghistory.monthly # Prefer monthly graphical over annual history reports\n" - "alias.burndown=burndown.weekly # Prefer the weekly burndown chart\n" - "\n" - "# Reports\n" - "\n" - "report.long.description=All details of tasks\n" - "report.long.labels=ID,A,Created,Mod,Deps,P,Project,Tags,Recur,Wait,Sched,Due,Until,Description\n" - "report.long.columns=id,start.active,entry,modified.age,depends,priority,project,tags,recur,wait.remaining,scheduled,due,until,description\n" - "report.long.filter=status:pending -WAITING\n" - "report.long.sort=modified-\n" - "report.long.context=1\n" - "\n" - "report.list.description=Most details of tasks\n" - "report.list.labels=ID,Active,Age,D,P,Project,Tags,R,Sch,Due,Until,Description,Urg\n" - "report.list.columns=id,start.age,entry.age,depends.indicator,priority,project,tags,recur.indicator,scheduled.countdown,due,until.remaining,description.count,urgency\n" - "report.list.filter=status:pending -WAITING\n" - "report.list.sort=start-,due+,project+,urgency-\n" - "report.list.context=1\n" - "\n" - "report.ls.description=Few details of tasks\n" - "report.ls.labels=ID,A,D,Project,Tags,R,Wait,S,Due,Until,Description\n" - "report.ls.columns=id,start.active,depends.indicator,project,tags,recur.indicator,wait.remaining,scheduled.countdown,due.countdown,until.countdown,description.count\n" - "report.ls.filter=status:pending -WAITING\n" - "report.ls.sort=start-,description+\n" - "report.ls.context=1\n" - "\n" - "report.minimal.description=Minimal details of tasks\n" - "report.minimal.labels=ID,Project,Tags,Description\n" - "report.minimal.columns=id,project,tags.count,description.count\n" - "report.minimal.filter=status:pending -WAITING\n" - "report.minimal.sort=project+/,description+\n" - "report.minimal.context=1\n" - "\n" - "report.newest.description=Newest tasks\n" - "report.newest.labels=ID,Active,Created,Age,Mod,D,P,Project,Tags,R,Wait,Sch,Due,Until,Description\n" - "report.newest.columns=id,start.age,entry,entry.age,modified.age,depends.indicator,priority,project,tags,recur.indicator,wait.remaining,scheduled.countdown,due,until.age,description\n" - "report.newest.filter=status:pending -WAITING\n" - "report.newest.sort=entry-\n" - "report.newest.context=1\n" - "\n" - "report.oldest.description=Oldest tasks\n" - "report.oldest.labels=ID,Active,Created,Age,Mod,D,P,Project,Tags,R,Wait,Sch,Due,Until,Description\n" - "report.oldest.columns=id,start.age,entry,entry.age,modified.age,depends.indicator,priority,project,tags,recur.indicator,wait.remaining,scheduled.countdown,due,until.age,description\n" - "report.oldest.filter=status:pending -WAITING\n" - "report.oldest.sort=entry+\n" - "report.oldest.context=1\n" - "\n" - "report.overdue.description=Overdue tasks\n" - "report.overdue.labels=ID,Active,Age,Deps,P,Project,Tag,R,S,Due,Until,Description,Urg\n" - "report.overdue.columns=id,start.age,entry.age,depends,priority,project,tags,recur.indicator,scheduled.countdown,due,until,description,urgency\n" - "report.overdue.filter=status:pending -WAITING +OVERDUE\n" - "report.overdue.sort=urgency-,due+\n" - "report.overdue.context=1\n" - "\n" - "report.active.description=Active tasks\n" - "report.active.labels=ID,Started,Active,Age,D,P,Project,Tags,Recur,W,Sch,Due,Until,Description\n" - "report.active.columns=id,start,start.age,entry.age,depends.indicator,priority,project,tags,recur,wait,scheduled.remaining,due,until,description\n" - "report.active.filter=status:pending -WAITING +ACTIVE\n" - "report.active.sort=project+,start+\n" - "report.active.context=1\n" - "\n" - "report.completed.description=Completed tasks\n" - "report.completed.labels=ID,UUID,Created,Completed,Age,Deps,P,Project,Tags,R,Due,Description\n" - "report.completed.columns=id,uuid.short,entry,end,entry.age,depends,priority,project,tags,recur.indicator,due,description\n" - "report.completed.filter=status:completed -WAITING \n" - "report.completed.sort=end+\n" - "report.completed.context=1\n" - "\n" - "report.recurring.description=Recurring Tasks\n" - "report.recurring.labels=ID,Active,Age,D,P,Parent,Project,Tags,Recur,Sch,Due,Until,Description,Urg\n" - "report.recurring.columns=id,start.age,entry.age,depends.indicator,priority,parent.short,project,tags,recur,scheduled.countdown,due,until.remaining,description,urgency\n" - "report.recurring.filter=(status:pending -WAITING +CHILD) or (status:recurring -WAITING +PARENT)\n" - "report.recurring.sort=due+,urgency-,entry+\n" - "report.recurring.context=1\n" - "\n" - "report.waiting.description=Waiting (hidden) tasks\n" - "report.waiting.labels=ID,A,Age,D,P,Project,Tags,R,Wait,Remaining,Sched,Due,Until,Description\n" - "report.waiting.columns=id,start.active,entry.age,depends.indicator,priority,project,tags,recur.indicator,wait,wait.remaining,scheduled,due,until,description\n" - "report.waiting.filter=+WAITING\n" - "report.waiting.sort=due+,wait+,entry+\n" - "report.waiting.context=1\n" - "\n" - "report.all.description=All tasks\n" - "report.all.labels=ID,St,UUID,A,Age,Done,D,P,Project,Tags,R,Wait,Sch,Due,Until,Description\n" - "report.all.columns=id,status.short,uuid.short,start.active,entry.age,end.age,depends.indicator,priority,project.parent,tags.count,recur.indicator,wait.remaining,scheduled.remaining,due,until.remaining,description\n" - "report.all.sort=entry-\n" - "report.all.context=1\n" - "\n" - "report.next.description=Most urgent tasks\n" - "report.next.labels=ID,Active,Age,Deps,P,Project,Tag,Recur,S,Due,Until,Description,Urg\n" - "report.next.columns=id,start.age,entry.age,depends,priority,project,tags,recur,scheduled.countdown,due.relative,until.remaining,description,urgency\n" - "report.next.filter=status:pending -WAITING limit:page\n" - "report.next.sort=urgency-\n" - "report.next.context=1\n" - "\n" - "report.ready.description=Most urgent actionable tasks\n" - "report.ready.labels=ID,Active,Age,D,P,Project,Tags,R,S,Due,Until,Description,Urg\n" - "report.ready.columns=id,start.age,entry.age,depends.indicator,priority,project,tags,recur.indicator,scheduled.countdown,due.countdown,until.remaining,description,urgency\n" - "report.ready.filter=+READY\n" - "report.ready.sort=start-,urgency-\n" - "report.ready.context=1\n" - "\n" - "report.blocked.description=Blocked tasks\n" - "report.blocked.columns=id,depends,project,priority,due,start.active,entry.age,description\n" - "report.blocked.labels=ID,Deps,Proj,Pri,Due,Active,Age,Description\n" - "report.blocked.sort=due+,priority-,start-,project+\n" - "report.blocked.filter=status:pending -WAITING +BLOCKED\n" - "report.blocked.context=1\n" - "\n" - "report.unblocked.description=Unblocked tasks\n" - "report.unblocked.columns=id,depends,project,priority,due,start.active,entry.age,description\n" - "report.unblocked.labels=ID,Deps,Proj,Pri,Due,Active,Age,Description\n" - "report.unblocked.sort=due+,priority-,start-,project+\n" - "report.unblocked.filter=status:pending -WAITING -BLOCKED\n" - "report.unblocked.context=1\n" - "\n" - "report.blocking.description=Blocking tasks\n" - "report.blocking.labels=ID,UUID,A,Deps,Project,Tags,R,W,Sch,Due,Until,Description,Urg\n" - "report.blocking.columns=id,uuid.short,start.active,depends,project,tags,recur,wait,scheduled.remaining,due.relative,until.remaining,description.count,urgency\n" - "report.blocking.sort=urgency-,due+,entry+\n" - "report.blocking.filter=status:pending -WAITING +BLOCKING\n" - "report.blocking.context=1\n" - "\n" - "report.timesheet.filter=(+PENDING -WAITING start.after:now-4wks) or (+COMPLETED -WAITING end.after:now-4wks)\n" - "report.timesheet.context=0\n" - "\n"; + "# Taskwarrior program configuration file.\n" + "# For more documentation, see https://taskwarrior.org or try 'man task', 'man task-color',\n" + "# 'man task-sync' or 'man taskrc'\n" + "\n" + "# Here is an example of entries that use the default, override and blank values\n" + "# variable=foo -- By specifying a value, this overrides the default\n" + "# variable= -- By specifying no value, this means no default\n" + "# #variable=foo -- By commenting out the line, or deleting it, this uses the default\n" + "\n" + "# You can also refence environment variables:\n" + "# variable=$HOME/task\n" + "# variable=$VALUE\n" + "\n" + "# Use the command 'task show' to see all defaults and overrides\n" + "\n" + "# Files\n" + "data.location=~/.task\n" + "gc=1 # Garbage-collect data files - DO NOT CHANGE " + "unless you are sure\n" + "exit.on.missing.db=0 # Whether to exit if ~/.task is not found\n" + "hooks=1 # Master control switch for hooks\n" + "\n" + "# Terminal\n" + "detection=1 # Detects terminal width\n" + "defaultwidth=80 # Without detection, assumed width\n" + "defaultheight=24 # Without detection, assumed height\n" + "avoidlastcolumn=0 # Fixes Cygwin width problem\n" + "hyphenate=1 # Hyphenates lines wrapped on non-word-breaks\n" + "#editor=vi # Preferred text editor\n" + "reserved.lines=1 # Assume a 1-line prompt\n" + "\n" + "# Miscellaneous\n" + "# verbose= # Comma-separated list. May contain any " + "subset of:\n" + "# " + "affected,blank,context,default,edit,filter,footnote,header,label,new-id,new-uuid,news," + "override,project,recur,special,sync\n" + "verbose=affected,blank,context,edit,header,footnote,label,new-id,news,project,special,sync," + "override,recur\n" + "confirmation=1 # Confirmation on delete, big changes\n" + "recurrence=1 # Enable recurrence\n" + "recurrence.confirmation=prompt # Confirmation for propagating changes among " + "recurring tasks (yes/no/prompt)\n" + "allow.empty.filter=1 # An empty filter gets a warning and requires " + "confirmation\n" + "indent.annotation=2 # Indent spaces for annotations\n" + "indent.report=0 # Indent spaces for whole report\n" + "row.padding=0 # Left and right padding for each row of " + "report\n" + "column.padding=1 # Spaces between each column in a report\n" + "bulk=3 # 3 or more tasks considered a bulk change and " + "is confirmed\n" + "nag=You have more urgent tasks. # Nag message to keep you honest\n" // TODO + "search.case.sensitive=1 # Setting to no allows case insensitive " + "searches\n" + "active.indicator=* # What to show as an active task indicator\n" + "tag.indicator=+ # What to show as a tag indicator\n" + "dependency.indicator=D # What to show as a dependency indicator\n" + "recurrence.indicator=R # What to show as a task recurrence indicator\n" + "recurrence.limit=1 # Number of future recurring pending tasks\n" + "undo.style=side # Undo style - can be 'side', or 'diff'\n" + "regex=1 # Assume all search/filter strings are " + "regexes\n" + "xterm.title=0 # Sets xterm title for some commands\n" + "expressions=infix # Prefer infix over postfix expressions\n" + "json.array=1 # Enclose JSON output in [ ]\n" + "abbreviation.minimum=2 # Shortest allowed abbreviation\n" + "news.version= # Latest version highlights read by the user\n" + "purge.on-sync=0 # Purge old tasks on sync\n" + "\n" + "# Dates\n" + "dateformat=Y-M-D # Preferred input and display date format\n" + "dateformat.holiday=YMD # Preferred input date format for holidays\n" + "dateformat.edit=Y-M-D H:N:S # Preferred display date format when editing\n" + "dateformat.info=Y-M-D H:N:S # Preferred display date format for " + "information\n" + "dateformat.report= # Preferred display date format for reports\n" + "dateformat.annotation= # Preferred display date format for " + "annotations\n" + "date.iso=1 # Enable ISO date support\n" + "weekstart=sunday # Sunday or Monday only\n" + "displayweeknumber=1 # Show week numbers on calendar\n" + "due=7 # Task is considered due in 7 days\n" + "\n" + "# Calendar controls\n" + "calendar.legend=1 # Display the legend on calendar\n" + "calendar.details=sparse # Calendar shows information for tasks w/due " + "dates: full, sparse or none\n" + "calendar.details.report=list # Report to use when showing task information " + "in cal\n" + "calendar.offset=0 # Apply an offset value to control the first " + "month of the calendar\n" + "calendar.offset.value=-1 # The number of months the first month of the " + "calendar is moved\n" + "calendar.holidays=none # Show public holidays on calendar:full, " + "sparse or none\n" + "#calendar.monthsperline=3 # Number of calendar months on a line\n" + "\n" + "# Journal controls\n" + "journal.time=0 # Record start/stop commands as annotation\n" + "journal.time.start.annotation=Started task # Annotation description for the start journal " + "entry\n" + "journal.time.stop.annotation=Stopped task # Annotation description for the stop journal " + "entry\n" + "journal.info=1 # Display task journal with info command\n" + "\n" + "# Dependency controls\n" + "dependency.reminder=1 # Nags on dependency chain violations\n" + "dependency.confirmation=1 # Should dependency chain repair be " + "confirmed?\n" + "\n" + "# Urgency Coefficients\n" + "urgency.user.tag.next.coefficient=15.0 # Urgency coefficient for 'next' special tag\n" + "urgency.due.coefficient=12.0 # Urgency coefficient for due dates\n" + "urgency.blocking.coefficient=8.0 # Urgency coefficient for blocking tasks\n" + "urgency.active.coefficient=4.0 # Urgency coefficient for active tasks\n" + "urgency.scheduled.coefficient=5.0 # Urgency coefficient for scheduled tasks\n" + "urgency.age.coefficient=2.0 # Urgency coefficient for age\n" + "urgency.annotations.coefficient=1.0 # Urgency coefficient for annotations\n" + "urgency.tags.coefficient=1.0 # Urgency coefficient for tags\n" + "urgency.project.coefficient=1.0 # Urgency coefficient for projects\n" + "urgency.blocked.coefficient=-5.0 # Urgency coefficient for blocked tasks\n" + "urgency.waiting.coefficient=-3.0 # Urgency coefficient for waiting status\n" + "urgency.inherit=0 # Recursively inherit highest urgency value " + "from blocked tasks\n" + "urgency.age.max=365 # Maximum age in days\n" + "\n" + "#urgency.user.project.foo.coefficient=5.0 # Urgency coefficients for 'foo' project\n" + "#urgency.user.tag.foo.coefficient=5.0 # Urgency coefficients for 'foo' tag\n" + "#urgency.uda.foo.coefficient=5.0 # Urgency coefficients for UDA 'foo'\n" + "\n" + "# Color controls.\n" + "color=1 # Enable color\n" + "\n" + "# Here is the rule precedence order, highest to lowest.\n" + "# Note that these are just the color rule names, without the leading 'color.'\n" + "# and any trailing '.value'.\n" + "rule.precedence.color=deleted,completed,active,keyword.,tag.,project.,overdue,scheduled,due." + "today,due,blocked,blocking,recurring,tagged,uda.\n" + "\n" + "# General decoration\n" + "rule.color.merge=1\n" + "color.label=\n" + "color.label.sort=\n" + "color.alternate=on gray2\n" + "color.header=color3\n" + "color.footnote=color3\n" + "color.warning=bold red\n" + "color.error=white on red\n" + "color.debug=color4\n" + "\n" + "# Task state\n" + "color.completed=\n" + "color.deleted=\n" + "color.active=rgb555 on rgb410\n" + "color.recurring=rgb013\n" + "color.scheduled=on rgb001\n" + "color.until=\n" + "color.blocked=white on color8\n" + "color.blocking=black on color15\n" + "\n" + "# Project\n" + "color.project.none=\n" + "\n" + "# Priority UDA\n" + "color.uda.priority.H=color255\n" + "color.uda.priority.L=color245\n" + "color.uda.priority.M=color250\n" + "\n" + "# Tags\n" + "color.tag.next=rgb440\n" + "color.tag.none=\n" + "color.tagged=rgb031\n" + "\n" + "# Due\n" + "color.due.today=rgb400\n" + "color.due=color1\n" + "color.overdue=color9\n" + "\n" + "# Report: burndown\n" + "color.burndown.done=on rgb010\n" + "color.burndown.pending=on color9\n" + "color.burndown.started=on color11\n" + "\n" + "# Report: history\n" + "color.history.add=color0 on rgb500\n" + "color.history.delete=color0 on rgb550\n" + "color.history.done=color0 on rgb050\n" + "\n" + "# Report: summary\n" + "color.summary.background=white on color0\n" + "color.summary.bar=black on rgb141\n" + "\n" + "# Command: calendar\n" + "color.calendar.due.today=color15 on color1\n" + "color.calendar.due=color0 on color1\n" + "color.calendar.holiday=color0 on color11\n" + "color.calendar.scheduled=rgb013 on color15\n" + "color.calendar.overdue=color0 on color9\n" + "color.calendar.today=color15 on rgb013\n" + "color.calendar.weekend=on color235\n" + "color.calendar.weeknumber=rgb013\n" + "\n" + "# Command: sync\n" + "color.sync.added=rgb010\n" + "color.sync.changed=color11\n" + "color.sync.rejected=color9\n" + "\n" + "# Command: undo\n" + "color.undo.after=color2\n" + "color.undo.before=color1\n" + "\n" + "# UDA priority\n" + "uda.priority.type=string # UDA priority is a string type\n" + "uda.priority.label=Priority # UDA priority has a display label'\n" + "uda.priority.values=H,M,L, # UDA priority values are 'H', 'M', 'L' or ''\n" + " # UDA priority sorting is 'H' > 'M' > 'L' > '' " + "(highest to lowest)\n" + "#uda.priority.default=M # UDA priority default value of 'M'\n" + "urgency.uda.priority.H.coefficient=6.0 # UDA priority coefficient for value 'H'\n" + "urgency.uda.priority.M.coefficient=3.9 # UDA priority coefficient for value 'M'\n" + "urgency.uda.priority.L.coefficient=1.8 # UDA priority coefficient for value 'L'\n" + "\n" + "#default.project=foo # Default project for 'add' command\n" + "#default.due=eom # Default due date for 'add' command\n" + "#default.scheduled=eom # Default scheduled date for 'add' command\n" + "default.command=next # When no arguments are specified\n" + "default.timesheet.filter=( +PENDING and start.after:now-4wks ) or ( +COMPLETED and " + "end.after:now-4wks )\n" + "\n" + "_forcecolor=0 # Forces color to be on, even for non TTY " + "output\n" + "complete.all.tags=0 # Include old tag names in '_ags' command\n" + "list.all.projects=0 # Include old project names in 'projects' " + "command\n" + "summary.all.projects=0 # Include old project names in 'summary' " + "command\n" + "list.all.tags=0 # Include old tag names in 'tags' command\n" + "print.empty.columns=0 # Print columns which have no data for any " + "task\n" + "debug=0 # Display diagnostics\n" + "sugar=1 # Syntactic sugar\n" + "obfuscate=0 # Obfuscate data for error reporting\n" + "fontunderline=1 # Uses underlines rather than -------\n" + "\n" + "# WARNING: Please read the documentation (man task-sync) before setting up\n" + "# Taskwarrior for Taskserver synchronization.\n" + "\n" + "#sync.encryption_secret # Encryption secret for sync to a server\n" + "#sync.server.client_id # Client ID for sync to a server\n" + "#sync.server.url # URL of the sync server\n" + "#sync.local.server_dir # Directory for local sync\n" + "#sync.gcp.credential_path # Path to JSON file containing credentials to " + "authenticate GCP Sync\n" + "#sync.gcp.bucket # Bucket for sync to GCP\n" + "\n" + "# Aliases - alternate names for commands\n" + "alias.rm=delete # Alias for the delete command\n" + "alias.history=history.monthly # Prefer monthly over annual history reports\n" + "alias.ghistory=ghistory.monthly # Prefer monthly graphical over annual history " + "reports\n" + "alias.burndown=burndown.weekly # Prefer the weekly burndown chart\n" + "\n" + "# Reports\n" + "\n" + "report.long.description=All details of tasks\n" + "report.long.labels=ID,A,Created,Mod,Deps,P,Project,Tags,Recur,Wait,Sched,Due,Until," + "Description\n" + "report.long.columns=id,start.active,entry,modified.age,depends,priority,project,tags,recur," + "wait.remaining,scheduled,due,until,description\n" + "report.long.filter=status:pending -WAITING\n" + "report.long.sort=modified-\n" + "report.long.context=1\n" + "\n" + "report.list.description=Most details of tasks\n" + "report.list.labels=ID,Active,Age,D,P,Project,Tags,R,Sch,Due,Until,Description,Urg\n" + "report.list.columns=id,start.age,entry.age,depends.indicator,priority,project,tags,recur." + "indicator,scheduled.countdown,due,until.remaining,description.count,urgency\n" + "report.list.filter=status:pending -WAITING\n" + "report.list.sort=start-,due+,project+,urgency-\n" + "report.list.context=1\n" + "\n" + "report.ls.description=Few details of tasks\n" + "report.ls.labels=ID,A,D,Project,Tags,R,Wait,S,Due,Until,Description\n" + "report.ls.columns=id,start.active,depends.indicator,project,tags,recur.indicator,wait." + "remaining,scheduled.countdown,due.countdown,until.countdown,description.count\n" + "report.ls.filter=status:pending -WAITING\n" + "report.ls.sort=start-,description+\n" + "report.ls.context=1\n" + "\n" + "report.minimal.description=Minimal details of tasks\n" + "report.minimal.labels=ID,Project,Tags,Description\n" + "report.minimal.columns=id,project,tags.count,description.count\n" + "report.minimal.filter=status:pending -WAITING\n" + "report.minimal.sort=project+/,description+\n" + "report.minimal.context=1\n" + "\n" + "report.newest.description=Newest tasks\n" + "report.newest.labels=ID,Active,Created,Age,Mod,D,P,Project,Tags,R,Wait,Sch,Due,Until," + "Description\n" + "report.newest.columns=id,start.age,entry,entry.age,modified.age,depends.indicator,priority," + "project,tags,recur.indicator,wait.remaining,scheduled.countdown,due,until.age,description\n" + "report.newest.filter=status:pending -WAITING\n" + "report.newest.sort=entry-\n" + "report.newest.context=1\n" + "\n" + "report.oldest.description=Oldest tasks\n" + "report.oldest.labels=ID,Active,Created,Age,Mod,D,P,Project,Tags,R,Wait,Sch,Due,Until," + "Description\n" + "report.oldest.columns=id,start.age,entry,entry.age,modified.age,depends.indicator,priority," + "project,tags,recur.indicator,wait.remaining,scheduled.countdown,due,until.age,description\n" + "report.oldest.filter=status:pending -WAITING\n" + "report.oldest.sort=entry+\n" + "report.oldest.context=1\n" + "\n" + "report.overdue.description=Overdue tasks\n" + "report.overdue.labels=ID,Active,Age,Deps,P,Project,Tag,R,S,Due,Until,Description,Urg\n" + "report.overdue.columns=id,start.age,entry.age,depends,priority,project,tags,recur.indicator," + "scheduled.countdown,due,until,description,urgency\n" + "report.overdue.filter=status:pending -WAITING +OVERDUE\n" + "report.overdue.sort=urgency-,due+\n" + "report.overdue.context=1\n" + "\n" + "report.active.description=Active tasks\n" + "report.active.labels=ID,Started,Active,Age,D,P,Project,Tags,Recur,W,Sch,Due,Until," + "Description\n" + "report.active.columns=id,start,start.age,entry.age,depends.indicator,priority,project,tags," + "recur,wait,scheduled.remaining,due,until,description\n" + "report.active.filter=status:pending -WAITING +ACTIVE\n" + "report.active.sort=project+,start+\n" + "report.active.context=1\n" + "\n" + "report.completed.description=Completed tasks\n" + "report.completed.labels=ID,UUID,Created,Completed,Age,Deps,P,Project,Tags,R,Due,Description\n" + "report.completed.columns=id,uuid.short,entry,end,entry.age,depends,priority,project,tags," + "recur.indicator,due,description\n" + "report.completed.filter=status:completed -WAITING \n" + "report.completed.sort=end+\n" + "report.completed.context=1\n" + "\n" + "report.recurring.description=Recurring Tasks\n" + "report.recurring.labels=ID,Active,Age,D,P,Parent,Project,Tags,Recur,Sch,Due,Until,Description," + "Urg\n" + "report.recurring.columns=id,start.age,entry.age,depends.indicator,priority,parent.short," + "project,tags,recur,scheduled.countdown,due,until.remaining,description,urgency\n" + "report.recurring.filter=(status:pending -WAITING +CHILD) or (status:recurring -WAITING " + "+PARENT)\n" + "report.recurring.sort=due+,urgency-,entry+\n" + "report.recurring.context=1\n" + "\n" + "report.waiting.description=Waiting (hidden) tasks\n" + "report.waiting.labels=ID,A,Age,D,P,Project,Tags,R,Wait,Remaining,Sched,Due,Until,Description\n" + "report.waiting.columns=id,start.active,entry.age,depends.indicator,priority,project,tags," + "recur.indicator,wait,wait.remaining,scheduled,due,until,description\n" + "report.waiting.filter=+WAITING\n" + "report.waiting.sort=due+,wait+,entry+\n" + "report.waiting.context=1\n" + "\n" + "report.all.description=All tasks\n" + "report.all.labels=ID,St,UUID,A,Age,Done,D,P,Project,Tags,R,Wait,Sch,Due,Until,Description\n" + "report.all.columns=id,status.short,uuid.short,start.active,entry.age,end.age,depends." + "indicator,priority,project.parent,tags.count,recur.indicator,wait.remaining,scheduled." + "remaining,due,until.remaining,description\n" + "report.all.sort=entry-\n" + "report.all.context=1\n" + "\n" + "report.next.description=Most urgent tasks\n" + "report.next.labels=ID,Active,Age,Deps,P,Project,Tag,Recur,S,Due,Until,Description,Urg\n" + "report.next.columns=id,start.age,entry.age,depends,priority,project,tags,recur,scheduled." + "countdown,due.relative,until.remaining,description,urgency\n" + "report.next.filter=status:pending -WAITING limit:page\n" + "report.next.sort=urgency-\n" + "report.next.context=1\n" + "\n" + "report.ready.description=Most urgent actionable tasks\n" + "report.ready.labels=ID,Active,Age,D,P,Project,Tags,R,S,Due,Until,Description,Urg\n" + "report.ready.columns=id,start.age,entry.age,depends.indicator,priority,project,tags,recur." + "indicator,scheduled.countdown,due.countdown,until.remaining,description,urgency\n" + "report.ready.filter=+READY\n" + "report.ready.sort=start-,urgency-\n" + "report.ready.context=1\n" + "\n" + "report.blocked.description=Blocked tasks\n" + "report.blocked.columns=id,depends,project,priority,due,start.active,entry.age,description\n" + "report.blocked.labels=ID,Deps,Proj,Pri,Due,Active,Age,Description\n" + "report.blocked.sort=due+,priority-,start-,project+\n" + "report.blocked.filter=status:pending -WAITING +BLOCKED\n" + "report.blocked.context=1\n" + "\n" + "report.unblocked.description=Unblocked tasks\n" + "report.unblocked.columns=id,depends,project,priority,due,start.active,entry.age,description\n" + "report.unblocked.labels=ID,Deps,Proj,Pri,Due,Active,Age,Description\n" + "report.unblocked.sort=due+,priority-,start-,project+\n" + "report.unblocked.filter=status:pending -WAITING -BLOCKED\n" + "report.unblocked.context=1\n" + "\n" + "report.blocking.description=Blocking tasks\n" + "report.blocking.labels=ID,UUID,A,Deps,Project,Tags,R,W,Sch,Due,Until,Description,Urg\n" + "report.blocking.columns=id,uuid.short,start.active,depends,project,tags,recur,wait,scheduled." + "remaining,due.relative,until.remaining,description.count,urgency\n" + "report.blocking.sort=urgency-,due+,entry+\n" + "report.blocking.filter=status:pending -WAITING +BLOCKING\n" + "report.blocking.context=1\n" + "\n" + "report.timesheet.filter=(+PENDING -WAITING start.after:now-4wks) or (+COMPLETED -WAITING " + "end.after:now-4wks)\n" + "report.timesheet.context=0\n" + "\n"; // Supported modifiers, synonyms on the same line. -static const char* modifierNames[] = -{ - "before", "under", "below", - "after", "over", "above", - "by", - "none", - "any", - "is", "equals", - "isnt", "not", - "has", "contains", - "hasnt", - "startswith", "left", - "endswith", "right", - "word", - "noword" -}; +static const char* modifierNames[] = { + "before", "under", "below", "after", "over", "above", "by", "none", + "any", "is", "equals", "isnt", "not", "has", "contains", "hasnt", + "startswith", "left", "endswith", "right", "word", "noword"}; Context* Context::context; //////////////////////////////////////////////////////////////////////////////// -Context& Context::getContext () -{ - assert (Context::context); +Context& Context::getContext() { + assert(Context::context); return *Context::context; } //////////////////////////////////////////////////////////////////////////////// -void Context::setContext (Context* context) -{ - Context::context = context; +void Context::setContext(Context* context) { Context::context = context; } + +//////////////////////////////////////////////////////////////////////////////// +Context::~Context() { + for (auto& com : commands) delete com.second; + + for (auto& col : columns) delete col.second; } //////////////////////////////////////////////////////////////////////////////// -Context::~Context () -{ - for (auto& com : commands) - delete com.second; - - for (auto& col : columns) - delete col.second; -} - -//////////////////////////////////////////////////////////////////////////////// -int Context::initialize (int argc, const char** argv) -{ - timer_total.start (); +int Context::initialize(int argc, const char** argv) { + timer_total.start(); int rc = 0; - home_dir = getenv ("HOME"); + home_dir = getenv("HOME"); - std::vector searchPaths { TASK_RCDIR }; + std::vector searchPaths{TASK_RCDIR}; - try - { + try { //////////////////////////////////////////////////////////////////////////// // // [1] Load the correct config file. @@ -489,51 +523,46 @@ int Context::initialize (int argc, const char** argv) bool taskrc_overridden = false; // XDG_CONFIG_HOME doesn't count as an override (no warning header) - if (! rc_file.exists ()) - { + if (!rc_file.exists()) { // Use XDG_CONFIG_HOME if defined, otherwise default to ~/.config std::string xdg_config_home; - const char* env_xdg_config_home = getenv ("XDG_CONFIG_HOME"); + const char* env_xdg_config_home = getenv("XDG_CONFIG_HOME"); if (env_xdg_config_home) - xdg_config_home = format ("{1}", env_xdg_config_home); + xdg_config_home = format("{1}", env_xdg_config_home); else - xdg_config_home = format ("{1}/.config", home_dir); + xdg_config_home = format("{1}/.config", home_dir); // Ensure the path does not end with '/' - if (xdg_config_home.back () == '/') - xdg_config_home.pop_back(); + if (xdg_config_home.back() == '/') xdg_config_home.pop_back(); // https://github.com/GothenburgBitFactory/libshared/issues/32 - std::string rcfile_path = format ("{1}/task/taskrc", xdg_config_home); + std::string rcfile_path = format("{1}/task/taskrc", xdg_config_home); - File maybe_rc_file = File (rcfile_path); - if ( maybe_rc_file.exists ()) - rc_file = maybe_rc_file; + File maybe_rc_file = File(rcfile_path); + if (maybe_rc_file.exists()) rc_file = maybe_rc_file; } - char *override = getenv ("TASKRC"); - if (override) - { - rc_file = File (override); + char* override = getenv("TASKRC"); + if (override) { + rc_file = File(override); taskrc_overridden = true; } - taskrc_overridden = - CLI2::getOverride (argc, argv, rc_file) || taskrc_overridden; + taskrc_overridden = CLI2::getOverride(argc, argv, rc_file) || taskrc_overridden; // Artificial scope for timing purposes. { Timer timer; - config.parse (configurationDefaults, 1, searchPaths); - config.load (rc_file._data, 1, searchPaths); - debugTiming (format ("Config::load ({1})", rc_file._data), timer); + config.parse(configurationDefaults, 1, searchPaths); + config.load(rc_file._data, 1, searchPaths); + debugTiming(format("Config::load ({1})", rc_file._data), timer); } - CLI2::applyOverrides (argc, argv); + CLI2::applyOverrides(argc, argv); - if (taskrc_overridden && verbose ("override")) - header (format ("TASKRC override: {1}", rc_file._data)); + if (taskrc_overridden && verbose("override")) + header(format("TASKRC override: {1}", rc_file._data)); //////////////////////////////////////////////////////////////////////////// // @@ -548,24 +577,22 @@ int Context::initialize (int argc, const char** argv) bool taskdata_overridden = false; - override = getenv ("TASKDATA"); - if (override) - { - data_dir = Directory (override); - config.set ("data.location", data_dir._data); + override = getenv("TASKDATA"); + if (override) { + data_dir = Directory(override); + config.set("data.location", data_dir._data); taskdata_overridden = true; } - taskdata_overridden = - CLI2::getDataLocation (argc, argv, data_dir) || taskdata_overridden; + taskdata_overridden = CLI2::getDataLocation(argc, argv, data_dir) || taskdata_overridden; - if (taskdata_overridden && verbose ("override")) - header (format ("TASKDATA override: {1}", data_dir._data)); + if (taskdata_overridden && verbose("override")) + header(format("TASKDATA override: {1}", data_dir._data)); - createDefaultConfig (); + createDefaultConfig(); - bool create_if_missing = !config.getBoolean ("exit.on.missing.db"); - tdb2.open_replica (data_dir, create_if_missing); + bool create_if_missing = !config.getBoolean("exit.on.missing.db"); + tdb2.open_replica(data_dir, create_if_missing); //////////////////////////////////////////////////////////////////////////// // @@ -573,9 +600,8 @@ int Context::initialize (int argc, const char** argv) // //////////////////////////////////////////////////////////////////////////// - Command::factory (commands); - for (auto& cmd : commands) - cli2.entity ("cmd", cmd.first); + Command::factory(commands); + for (auto& cmd : commands) cli2.entity("cmd", cmd.first); //////////////////////////////////////////////////////////////////////////// // @@ -583,11 +609,10 @@ int Context::initialize (int argc, const char** argv) // //////////////////////////////////////////////////////////////////////////// - Column::factory (columns); - for (auto& col : columns) - cli2.entity ("attribute", col.first); + Column::factory(columns); + for (auto& col : columns) cli2.entity("attribute", col.first); - cli2.entity ("pseudo", "limit"); + cli2.entity("pseudo", "limit"); //////////////////////////////////////////////////////////////////////////// // @@ -595,14 +620,11 @@ int Context::initialize (int argc, const char** argv) // //////////////////////////////////////////////////////////////////////////// - for (auto& modifierName : modifierNames) - cli2.entity ("modifier", modifierName); + for (auto& modifierName : modifierNames) cli2.entity("modifier", modifierName); - for (auto& op : Eval::getOperators ()) - cli2.entity ("operator", op); + for (auto& op : Eval::getOperators()) cli2.entity("operator", op); - for (auto& op : Eval::getBinaryOperators ()) - cli2.entity ("binary_operator", op); + for (auto& op : Eval::getBinaryOperators()) cli2.entity("binary_operator", op); //////////////////////////////////////////////////////////////////////////// // @@ -610,10 +632,10 @@ int Context::initialize (int argc, const char** argv) // //////////////////////////////////////////////////////////////////////////// - initializeColorRules (); - staticInitialization (); - propagateDebug (); - loadAliases (); + initializeColorRules(); + staticInitialization(); + propagateDebug(); + loadAliases(); //////////////////////////////////////////////////////////////////////////// // @@ -621,35 +643,28 @@ int Context::initialize (int argc, const char** argv) // //////////////////////////////////////////////////////////////////////////// - for (int i = 0; i < argc; i++) - cli2.add (argv[i]); + for (int i = 0; i < argc; i++) cli2.add(argv[i]); - cli2.analyze (); + cli2.analyze(); // Extract a recomposed command line. auto foundDefault = false; auto foundAssumed = false; std::string combined; - for (auto& a : cli2._args) - { - if (combined.length ()) - combined += ' '; + for (auto& a : cli2._args) { + if (combined.length()) combined += ' '; - combined += a.attribute ("raw"); + combined += a.attribute("raw"); - if (a.hasTag ("DEFAULT")) - foundDefault = true; + if (a.hasTag("DEFAULT")) foundDefault = true; - if (a.hasTag ("ASSUMED")) - foundAssumed = true; + if (a.hasTag("ASSUMED")) foundAssumed = true; } - if (verbose ("default")) { - if (foundDefault) - header ("[" + combined + "]"); + if (verbose("default")) { + if (foundDefault) header("[" + combined + "]"); - if (foundAssumed) - header ("No command specified - assuming 'information'."); + if (foundAssumed) header("No command specified - assuming 'information'."); } //////////////////////////////////////////////////////////////////////////// @@ -658,60 +673,51 @@ int Context::initialize (int argc, const char** argv) // //////////////////////////////////////////////////////////////////////////// - hooks.initialize (); + hooks.initialize(); } - catch (const std::string& message) - { - error (message); + catch (const std::string& message) { + error(message); rc = 2; } - catch (int) - { + catch (int) { // Hooks can terminate processing by throwing integers. rc = 4; } - catch (const std::regex_error& e) - { + catch (const std::regex_error& e) { std::cout << "regex_error caught: " << e.what() << '\n'; - } - catch (...) - { - error ("knknown error. Please report."); + } catch (...) { + error("knknown error. Please report."); rc = 3; } // On initialization failure... - if (rc) - { + if (rc) { // Dump all debug messages, controlled by rc.debug. - if (config.getBoolean ("debug")) - { + if (config.getBoolean("debug")) { for (auto& d : debugMessages) - if (color ()) - std::cerr << colorizeDebug (d) << '\n'; + if (color()) + std::cerr << colorizeDebug(d) << '\n'; else std::cerr << d << '\n'; } // Dump all headers, controlled by 'header' verbosity token. - if (verbose ("header")) - { + if (verbose("header")) { for (auto& h : headers) - if (color ()) - std::cerr << colorizeHeader (h) << '\n'; + if (color()) + std::cerr << colorizeHeader(h) << '\n'; else std::cerr << h << '\n'; } // Dump all footnotes, controlled by 'footnote' verbosity token. - if (verbose ("footnote")) - { + if (verbose("footnote")) { for (auto& f : footnotes) - if (color ()) - std::cerr << colorizeFootnote (f) << '\n'; + if (color()) + std::cerr << colorizeFootnote(f) << '\n'; else std::cerr << f << '\n'; } @@ -719,98 +725,77 @@ int Context::initialize (int argc, const char** argv) // Dump all errors, non-maskable. // Colorized as footnotes. for (auto& e : errors) - if (color ()) - std::cerr << colorizeFootnote (e) << '\n'; + if (color()) + std::cerr << colorizeFootnote(e) << '\n'; else std::cerr << e << '\n'; } - time_init_us += timer_total.total_us (); + time_init_us += timer_total.total_us(); return rc; } //////////////////////////////////////////////////////////////////////////////// -int Context::run () -{ +int Context::run() { int rc; std::string output; - try - { - hooks.onLaunch (); - rc = dispatch (output); - hooks.onExit (); // No chance to update data. + try { + hooks.onLaunch(); + rc = dispatch(output); + hooks.onExit(); // No chance to update data. - timer_total.stop (); - time_total_us += timer_total.total_us (); + timer_total.stop(); + time_total_us += timer_total.total_us(); std::stringstream s; - s << "Perf " - << PACKAGE_STRING - << ' ' + s << "Perf " << PACKAGE_STRING << ' ' #ifdef HAVE_COMMIT << COMMIT #else << '-' #endif - << ' ' - << Datetime ().toISO () + << ' ' << Datetime().toISO() - << " init:" << time_init_us - << " load:" << time_load_us - << " gc:" << (time_gc_us > 0 ? time_gc_us - time_load_us : time_gc_us) - << " filter:" << time_filter_us - << " commit:" << time_commit_us - << " sort:" << time_sort_us - << " render:" << time_render_us - << " hooks:" << time_hooks_us - << " other:" << time_total_us - - time_init_us - - time_gc_us - - time_filter_us - - time_commit_us - - time_sort_us - - time_render_us - - time_hooks_us - << " total:" << time_total_us - << '\n'; - debug (s.str ()); + << " init:" << time_init_us << " load:" << time_load_us + << " gc:" << (time_gc_us > 0 ? time_gc_us - time_load_us : time_gc_us) + << " filter:" << time_filter_us << " commit:" << time_commit_us << " sort:" << time_sort_us + << " render:" << time_render_us << " hooks:" << time_hooks_us << " other:" + << time_total_us - time_init_us - time_gc_us - time_filter_us - time_commit_us - + time_sort_us - time_render_us - time_hooks_us + << " total:" << time_total_us << '\n'; + debug(s.str()); } - catch (const std::string& message) - { - error (message); + catch (const std::string& message) { + error(message); rc = 2; } - catch (int) - { + catch (int) { // Hooks can terminate processing by throwing integers. rc = 4; } - catch (...) - { - error ("Unknown error. Please report."); + catch (...) { + error("Unknown error. Please report."); rc = 3; } // Dump all debug messages, controlled by rc.debug. - if (config.getBoolean ("debug")) - { + if (config.getBoolean("debug")) { for (auto& d : debugMessages) - if (color ()) - std::cerr << colorizeDebug (d) << '\n'; + if (color()) + std::cerr << colorizeDebug(d) << '\n'; else std::cerr << d << '\n'; } // Dump all headers, controlled by 'header' verbosity token. - if (verbose ("header")) - { + if (verbose("header")) { for (auto& h : headers) - if (color ()) - std::cerr << colorizeHeader (h) << '\n'; + if (color()) + std::cerr << colorizeHeader(h) << '\n'; else std::cerr << h << '\n'; } @@ -819,11 +804,10 @@ int Context::run () std::cout << output; // Dump all footnotes, controlled by 'footnote' verbosity token. - if (verbose ("footnote")) - { + if (verbose("footnote")) { for (auto& f : footnotes) - if (color ()) - std::cerr << colorizeFootnote (f) << '\n'; + if (color()) + std::cerr << colorizeFootnote(f) << '\n'; else std::cerr << f << '\n'; } @@ -831,8 +815,8 @@ int Context::run () // Dump all errors, non-maskable. // Colorized as footnotes. for (auto& e : errors) - if (color ()) - std::cerr << colorizeError (e) << '\n'; + if (color()) + std::cerr << colorizeError(e) << '\n'; else std::cerr << e << '\n'; @@ -841,64 +825,52 @@ int Context::run () //////////////////////////////////////////////////////////////////////////////// // Dispatch to the command found by the CLI parser. -int Context::dispatch (std::string &out) -{ +int Context::dispatch(std::string& out) { // Autocomplete args against keywords. - std::string command = cli2.getCommand (); - if (command != "") - { - updateXtermTitle (); - updateVerbosity (); + std::string command = cli2.getCommand(); + if (command != "") { + updateXtermTitle(); + updateVerbosity(); Command* c = commands[command]; - assert (c); + assert(c); // The command know whether they need a GC. - if (c->needs_gc ()) - { - tdb2.gc (); + if (c->needs_gc()) { + tdb2.gc(); } // This is something that is only needed for write commands with no other // filter processing. - if (c->accepts_modifications () && - ! c->accepts_filter ()) - { - cli2.prepareFilter (); + if (c->accepts_modifications() && !c->accepts_filter()) { + cli2.prepareFilter(); } // With rc.debug.parser == 2, there are more tree dumps than you might want, // but we need the rc.debug.parser == 1 case covered also, with the final // tree. - if (config.getBoolean ("debug") && - config.getInteger ("debug.parser") == 1) - debug (cli2.dump ("Parse Tree (before command-specifіc processing)")); + if (config.getBoolean("debug") && config.getInteger("debug.parser") == 1) + debug(cli2.dump("Parse Tree (before command-specifіc processing)")); - return c->execute (out); + return c->execute(out); } - assert (commands["help"]); - return commands["help"]->execute (out); + assert(commands["help"]); + return commands["help"]->execute(out); } //////////////////////////////////////////////////////////////////////////////// -int Context::getWidth () -{ +int Context::getWidth() { // Determine window size. - auto width = config.getInteger ("defaultwidth"); + auto width = config.getInteger("defaultwidth"); // A zero width value means 'infinity', which is approximated here by 2^16. - if (width == 0) - return 65536; + if (width == 0) return 65536; - if (config.getBoolean ("detection")) - { - if (terminal_width == 0 && - terminal_height == 0) - { + if (config.getBoolean("detection")) { + if (terminal_width == 0 && terminal_height == 0) { unsigned short buff[4]; - if (ioctl (STDOUT_FILENO, TIOCGWINSZ, &buff) != -1) - { + if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &buff) != -1) { terminal_height = buff[0]; terminal_width = buff[1]; } @@ -909,31 +881,24 @@ int Context::getWidth () // Ncurses does this, and perhaps we need to as well, to avoid a problem on // Cygwin where the display goes right up to the terminal width, and causes // an odd color wrapping problem. - if (config.getBoolean ("avoidlastcolumn")) - --width; + if (config.getBoolean("avoidlastcolumn")) --width; } return width; } //////////////////////////////////////////////////////////////////////////////// -int Context::getHeight () -{ +int Context::getHeight() { // Determine window size. - auto height = config.getInteger ("defaultheight"); + auto height = config.getInteger("defaultheight"); // A zero height value means 'infinity', which is approximated here by 2^16. - if (height == 0) - return 65536; + if (height == 0) return 65536; - if (config.getBoolean ("detection")) - { - if (terminal_width == 0 && - terminal_height == 0) - { + if (config.getBoolean("detection")) { + if (terminal_width == 0 && terminal_height == 0) { unsigned short buff[4]; - if (ioctl (STDOUT_FILENO, TIOCGWINSZ, &buff) != -1) - { + if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &buff) != -1) { terminal_height = buff[0]; terminal_width = buff[1]; } @@ -946,63 +911,54 @@ int Context::getHeight () } //////////////////////////////////////////////////////////////////////////////// -std::string Context::getTaskContext (const std::string& kind, std::string name, bool fallback /* = true */) -{ +std::string Context::getTaskContext(const std::string& kind, std::string name, + bool fallback /* = true */) { // Consider currently selected context, if none specified - if (name.empty ()) - name = config.get ("context"); + if (name.empty()) name = config.get("context"); // Detect if any context is set, and bail out if not - if (! name.empty ()) - debug (format ("Applying context '{1}'", name)); - else - { - debug ("No context set"); + if (!name.empty()) + debug(format("Applying context '{1}'", name)); + else { + debug("No context set"); return ""; } // Figure out the context string for this kind (read/write) std::string contextString = ""; - if (! config.has ("context." + name + "." + kind) && kind == "read") - { - debug ("Specific " + kind + " context for '" + name + "' not defined. "); - if (fallback) - { - debug ("Trying to interpret old-style context definition as read context."); - contextString = config.get ("context." + name); + if (!config.has("context." + name + "." + kind) && kind == "read") { + debug("Specific " + kind + " context for '" + name + "' not defined. "); + if (fallback) { + debug("Trying to interpret old-style context definition as read context."); + contextString = config.get("context." + name); } - } - else - contextString = config.get ("context." + name + "." + kind); + } else + contextString = config.get("context." + name + "." + kind); - debug (format ("Detected context string: {1}", contextString.empty() ? "(empty)" : contextString)); + debug(format("Detected context string: {1}", contextString.empty() ? "(empty)" : contextString)); return contextString; } //////////////////////////////////////////////////////////////////////////////// -bool Context::color () -{ - if (determine_color_use) - { +bool Context::color() { + if (determine_color_use) { // What the config says. - use_color = config.getBoolean ("color"); + use_color = config.getBoolean("color"); // Only tty's support color. - if (! isatty (STDOUT_FILENO)) - { + if (!isatty(STDOUT_FILENO)) { // No ioctl. - config.set ("detection", "off"); - config.set ("color", "off"); + 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"); + if (config.getBoolean("_forcecolor")) { + config.set("color", "on"); use_color = true; } @@ -1025,67 +981,55 @@ bool Context::color () // TODO This mechanism is clunky, and should slowly evolve into something more // logical and consistent. This should probably mean that 'nothing' should // take the place of '0'. -bool Context::verbose (const std::string& token) -{ - if (verbosity.empty ()) - { - verbosity_legacy = config.getBoolean ("verbose"); - for (auto& token : split (config.get ("verbose"), ',')) - verbosity.insert (token); +bool Context::verbose(const std::string& token) { + if (verbosity.empty()) { + verbosity_legacy = config.getBoolean("verbose"); + for (auto& token : split(config.get("verbose"), ',')) verbosity.insert(token); // Regular feedback means almost everything. // This odd test is to see if a Boolean-false value is a real one, which // means it is not 1/true/T/yes/on, but also should not be one of the // valid tokens either. - if (! verbosity_legacy && ! verbosity.empty ()) - { - std::string v = *(verbosity.begin ()); - if (v != "nothing" && - v != "affected" && // This list must be complete. - v != "blank" && // - v != "context" && // - v != "default" && // - v != "edit" && // - v != "filter" && // - v != "footnote" && // - v != "header" && // - v != "label" && // - v != "new-id" && // - v != "new-uuid" && // - v != "news" && // - v != "override" && // - v != "project" && // - v != "recur" && // - v != "special" && // - v != "sync") - { + if (!verbosity_legacy && !verbosity.empty()) { + std::string v = *(verbosity.begin()); + if (v != "nothing" && v != "affected" && // This list must be complete. + v != "blank" && // + v != "context" && // + v != "default" && // + v != "edit" && // + v != "filter" && // + v != "footnote" && // + v != "header" && // + v != "label" && // + v != "new-id" && // + v != "new-uuid" && // + v != "news" && // + v != "override" && // + v != "project" && // + v != "recur" && // + v != "special" && // + v != "sync") { // This list emulates rc.verbose=off in version 1.9.4. verbosity = {"blank", "label", "new-id", "edit"}; } } // Some flags imply "footnote" verbosity being active. Make it so. - if (! verbosity.count ("footnote")) - { + if (!verbosity.count("footnote")) { // TODO: Some of these may not use footnotes yet. They should. - for (auto flag : {"affected", "new-id", "new-uuid", "project", "override", "recur"}) - { - if (verbosity.count (flag)) - { - verbosity.insert ("footnote"); + for (auto flag : {"affected", "new-id", "new-uuid", "project", "override", "recur"}) { + if (verbosity.count(flag)) { + verbosity.insert("footnote"); break; } } } // Some flags imply "header" verbosity being active. Make it so. - if (! verbosity.count ("header")) - { - for (auto flag : {"default"}) - { - if (verbosity.count (flag)) - { - verbosity.insert ("header"); + if (!verbosity.count("header")) { + for (auto flag : {"default"}) { + if (verbosity.count(flag)) { + verbosity.insert("header"); break; } } @@ -1093,27 +1037,21 @@ bool Context::verbose (const std::string& token) } // rc.verbose=true|y|yes|1|on overrides all. - if (verbosity_legacy) - return true; + if (verbosity_legacy) return true; // rc.verbose=nothing overrides all. - if (verbosity.size () == 1 && - *(verbosity.begin ()) == "nothing") - return false; + if (verbosity.size() == 1 && *(verbosity.begin()) == "nothing") return false; // Specific token match. - if (verbosity.count (token)) - return true; + if (verbosity.count(token)) return true; return false; } //////////////////////////////////////////////////////////////////////////////// -const std::vector Context::getColumns () const -{ - std::vector output; - for (auto& col : columns) - output.push_back (col.first); +const std::vector Context::getColumns() const { + std::vector output; + for (auto& col : columns) output.push_back(col.first); return output; } @@ -1122,23 +1060,18 @@ const std::vector Context::getColumns () const // A value of zero mean unlimited. // A value of 'page' means however many screen lines there are. // A value of a positive integer is a row/task limit. -void Context::getLimits (int& rows, int& lines) -{ +void Context::getLimits(int& rows, int& lines) { rows = 0; lines = 0; // This is an integer specified as a filter (limit:10). - auto limit = config.get ("limit"); - if (limit != "") - { - if (limit == "page") - { + auto limit = config.get("limit"); + if (limit != "") { + if (limit == "page") { rows = 0; - lines = getHeight (); - } - else - { - rows = (int) strtol (limit.c_str (), nullptr, 10); + lines = getHeight(); + } else { + rows = (int)strtol(limit.c_str(), nullptr, 10); lines = 0; } } @@ -1147,85 +1080,76 @@ void Context::getLimits (int& rows, int& lines) //////////////////////////////////////////////////////////////////////////////// // The 'Task' object, among others, is shared between projects. To make this // easier, it has been decoupled from Context. -void Context::staticInitialization () -{ - CLI2::minimumMatchLength = config.getInteger ("abbreviation.minimum"); - Lexer::minimumMatchLength = config.getInteger ("abbreviation.minimum"); +void Context::staticInitialization() { + CLI2::minimumMatchLength = config.getInteger("abbreviation.minimum"); + Lexer::minimumMatchLength = config.getInteger("abbreviation.minimum"); - Task::defaultProject = config.get ("default.project"); - Task::defaultDue = config.get ("default.due"); - Task::defaultScheduled = config.get ("default.scheduled"); + Task::defaultProject = config.get("default.project"); + Task::defaultDue = config.get("default.due"); + Task::defaultScheduled = config.get("default.scheduled"); - Task::searchCaseSensitive = Variant::searchCaseSensitive = config.getBoolean ("search.case.sensitive"); - Task::regex = Variant::searchUsingRegex = config.getBoolean ("regex"); - Lexer::dateFormat = Variant::dateFormat = config.get ("dateformat"); + Task::searchCaseSensitive = Variant::searchCaseSensitive = + config.getBoolean("search.case.sensitive"); + Task::regex = Variant::searchUsingRegex = config.getBoolean("regex"); + Lexer::dateFormat = Variant::dateFormat = config.get("dateformat"); - Datetime::isoEnabled = config.getBoolean ("date.iso"); - Datetime::standaloneDateEnabled = false; - Datetime::standaloneTimeEnabled = false; + Datetime::isoEnabled = config.getBoolean("date.iso"); + Datetime::standaloneDateEnabled = false; + Datetime::standaloneTimeEnabled = false; Duration::standaloneSecondsEnabled = false; - TDB2::debug_mode = config.getBoolean ("debug"); + TDB2::debug_mode = config.getBoolean("debug"); - for (auto& rc : config) - { - if (rc.first.substr (0, 4) == "uda." && - rc.first.substr (rc.first.length () - 7, 7) == ".values") - { - std::string name = rc.first.substr (4, rc.first.length () - 7 - 4); - auto values = split (rc.second, ','); + for (auto& rc : config) { + if (rc.first.substr(0, 4) == "uda." && rc.first.substr(rc.first.length() - 7, 7) == ".values") { + std::string name = rc.first.substr(4, rc.first.length() - 7 - 4); + auto values = split(rc.second, ','); - for (auto r = values.rbegin(); r != values.rend (); ++r) - Task::customOrder[name].push_back (*r); + for (auto r = values.rbegin(); r != values.rend(); ++r) Task::customOrder[name].push_back(*r); } } - for (auto& col : columns) - { - Task::attributes[col.first] = col.second->type (); - Lexer::attributes[col.first] = col.second->type (); + for (auto& col : columns) { + Task::attributes[col.first] = col.second->type(); + Lexer::attributes[col.first] = col.second->type(); } - Task::urgencyProjectCoefficient = config.getReal ("urgency.project.coefficient"); - Task::urgencyActiveCoefficient = config.getReal ("urgency.active.coefficient"); - Task::urgencyScheduledCoefficient = config.getReal ("urgency.scheduled.coefficient"); - Task::urgencyWaitingCoefficient = config.getReal ("urgency.waiting.coefficient"); - Task::urgencyBlockedCoefficient = config.getReal ("urgency.blocked.coefficient"); - Task::urgencyAnnotationsCoefficient = config.getReal ("urgency.annotations.coefficient"); - Task::urgencyTagsCoefficient = config.getReal ("urgency.tags.coefficient"); - Task::urgencyDueCoefficient = config.getReal ("urgency.due.coefficient"); - Task::urgencyBlockingCoefficient = config.getReal ("urgency.blocking.coefficient"); - Task::urgencyAgeCoefficient = config.getReal ("urgency.age.coefficient"); - Task::urgencyAgeMax = config.getReal ("urgency.age.max"); + Task::urgencyProjectCoefficient = config.getReal("urgency.project.coefficient"); + Task::urgencyActiveCoefficient = config.getReal("urgency.active.coefficient"); + Task::urgencyScheduledCoefficient = config.getReal("urgency.scheduled.coefficient"); + Task::urgencyWaitingCoefficient = config.getReal("urgency.waiting.coefficient"); + Task::urgencyBlockedCoefficient = config.getReal("urgency.blocked.coefficient"); + Task::urgencyAnnotationsCoefficient = config.getReal("urgency.annotations.coefficient"); + Task::urgencyTagsCoefficient = config.getReal("urgency.tags.coefficient"); + Task::urgencyDueCoefficient = config.getReal("urgency.due.coefficient"); + Task::urgencyBlockingCoefficient = config.getReal("urgency.blocking.coefficient"); + Task::urgencyAgeCoefficient = config.getReal("urgency.age.coefficient"); + Task::urgencyAgeMax = config.getReal("urgency.age.max"); // Tag- and project-specific coefficients. - for (auto& var : config.all ()) - if (var.substr (0, 13) == "urgency.user." || - var.substr (0, 12) == "urgency.uda.") - Task::coefficients[var] = config.getReal (var); + for (auto& var : config.all()) + if (var.substr(0, 13) == "urgency.user." || var.substr(0, 12) == "urgency.uda.") + Task::coefficients[var] = config.getReal(var); } //////////////////////////////////////////////////////////////////////////////// -void Context::createDefaultConfig () -{ +void Context::createDefaultConfig() { // Do we need to create a default rc? - if (rc_file._data != "" && ! rc_file.exists ()) - { - if (config.getBoolean ("confirmation") && - ! confirm ( format ("A configuration file could not be found in {1}\n\nWould you like a sample {2} created, so Taskwarrior can proceed?", home_dir, rc_file._data))) - throw std::string ("Cannot proceed without rc file."); + if (rc_file._data != "" && !rc_file.exists()) { + if (config.getBoolean("confirmation") && + !confirm(format("A configuration file could not be found in {1}\n\nWould you like a sample " + "{2} created, so Taskwarrior can proceed?", + home_dir, rc_file._data))) + throw std::string("Cannot proceed without rc file."); Datetime now; std::stringstream contents; - contents << "# [Created by " - << PACKAGE_STRING - << ' ' - << now.toString ("m/d/Y H:N:S") - << "]\n" + contents << "# [Created by " << PACKAGE_STRING << ' ' << now.toString("m/d/Y H:N:S") << "]\n" << "data.location=" << data_dir._original << "\n" << "news.version=" << Version::Current() << "\n" << "\n# To use the default location of the XDG directories,\n" - << "# move this configuration file from ~/.taskrc to ~/.config/task/taskrc and update location config as follows:\n" + << "# move this configuration file from ~/.taskrc to ~/.config/task/taskrc and update " + "location config as follows:\n" << "\n#data.location=~/.local/share/task\n" << "#hooks.location=~/.config/task/hooks\n" << "\n# Color theme (uncomment one to use)\n" @@ -1246,8 +1170,8 @@ void Context::createDefaultConfig () << '\n'; // Write out the new file. - if (! File::write (rc_file._data, contents.str ())) - throw format ("Could not write to '{1}'.", rc_file._data); + if (!File::write(rc_file._data, contents.str())) + throw format("Could not write to '{1}'.", rc_file._data); // Load it so that it takes effect for this run. config.load(rc_file); @@ -1255,75 +1179,52 @@ void Context::createDefaultConfig () } //////////////////////////////////////////////////////////////////////////////// -void Context::decomposeSortField ( - const std::string& field, - std::string& key, - bool& ascending, - bool& breakIndicator) -{ - int length = field.length (); +void Context::decomposeSortField(const std::string& field, std::string& key, bool& ascending, + bool& breakIndicator) { + int length = field.length(); int decoration = 1; breakIndicator = false; - if (field[length - decoration] == '/') - { + if (field[length - decoration] == '/') { breakIndicator = true; ++decoration; } - if (field[length - decoration] == '+') - { + if (field[length - decoration] == '+') { ascending = true; - key = field.substr (0, length - decoration); - } - else if (field[length - decoration] == '-') - { + key = field.substr(0, length - decoration); + } else if (field[length - decoration] == '-') { ascending = false; - key = field.substr (0, length - decoration); - } - else - { + key = field.substr(0, length - decoration); + } else { ascending = true; key = field; } } //////////////////////////////////////////////////////////////////////////////// -void Context::debugTiming (const std::string& details, const Timer& timer) -{ +void Context::debugTiming(const std::string& details, const Timer& timer) { std::stringstream out; - out << "Timer " - << details - << ' ' - << std::setprecision (6) - << std::fixed - << timer.total_us () / 1.0e6 - << " sec"; - debug (out.str ()); + out << "Timer " << details << ' ' << std::setprecision(6) << std::fixed + << timer.total_us() / 1.0e6 << " sec"; + debug(out.str()); } //////////////////////////////////////////////////////////////////////////////// -CurrentTask Context::withCurrentTask (const Task *task) -{ - return CurrentTask(*this, task); -} +CurrentTask Context::withCurrentTask(const Task* task) { return CurrentTask(*this, task); } //////////////////////////////////////////////////////////////////////////////// // This capability is to answer the question of 'what did I just do to generate // this output?'. -void Context::updateXtermTitle () -{ - if (config.getBoolean ("xterm.title") && isatty (STDOUT_FILENO)) - { - auto command = cli2.getCommand (); +void Context::updateXtermTitle() { + if (config.getBoolean("xterm.title") && isatty(STDOUT_FILENO)) { + auto command = cli2.getCommand(); std::string title; - for (auto a = cli2._args.begin (); a != cli2._args.end (); ++a) - { - if (a != cli2._args.begin ()) - title += ' '; + for (auto a = cli2._args.begin(); a != cli2._args.end(); ++a) { + if (a != cli2._args.begin()) title += ' '; - title += a->attribute ("raw"); + title += a->attribute("raw"); } std::cout << "]0;task " << command << ' ' << title << ""; @@ -1332,92 +1233,69 @@ void Context::updateXtermTitle () //////////////////////////////////////////////////////////////////////////////// // This function allows a clean output if the command is a helper subcommand. -void Context::updateVerbosity () -{ - auto command = cli2.getCommand (); - if (command != "" && - command[0] == '_') - { +void Context::updateVerbosity() { + auto command = cli2.getCommand(); + if (command != "" && command[0] == '_') { verbosity = {"nothing"}; } } //////////////////////////////////////////////////////////////////////////////// -void Context::loadAliases () -{ +void Context::loadAliases() { for (auto& i : config) - if (i.first.substr (0, 6) == "alias.") - cli2.alias (i.first.substr (6), i.second); + if (i.first.substr(0, 6) == "alias.") cli2.alias(i.first.substr(6), i.second); } //////////////////////////////////////////////////////////////////////////////// // Using the general rc.debug setting automaticalls sets debug.hooks // and debug.parser, unless they already have values, which by default they do // not. -void Context::propagateDebug () -{ - if (config.getBoolean ("debug")) - { - if (! config.has ("debug.hooks")) - config.set ("debug.hooks", 1); +void Context::propagateDebug() { + if (config.getBoolean("debug")) { + if (!config.has("debug.hooks")) config.set("debug.hooks", 1); - if (! config.has ("debug.parser")) - config.set ("debug.parser", 1); - } - else - { - if ((config.has ("debug.hooks") && config.getInteger ("debug.hooks")) || - (config.has ("debug.parser") && config.getInteger ("debug.parser")) ) - config.set ("debug", true); + if (!config.has("debug.parser")) config.set("debug.parser", 1); + } else { + if ((config.has("debug.hooks") && config.getInteger("debug.hooks")) || + (config.has("debug.parser") && config.getInteger("debug.parser"))) + config.set("debug", true); } } //////////////////////////////////////////////////////////////////////////////// // No duplicates. -void Context::header (const std::string& input) -{ - if (input.length () && - std::find (headers.begin (), headers.end (), input) == headers.end ()) - headers.push_back (input); +void Context::header(const std::string& input) { + if (input.length() && std::find(headers.begin(), headers.end(), input) == headers.end()) + headers.push_back(input); } //////////////////////////////////////////////////////////////////////////////// // No duplicates. -void Context::footnote (const std::string& input) -{ - if (input.length () && - std::find (footnotes.begin (), footnotes.end (), input) == footnotes.end ()) - footnotes.push_back (input); +void Context::footnote(const std::string& input) { + if (input.length() && std::find(footnotes.begin(), footnotes.end(), input) == footnotes.end()) + footnotes.push_back(input); } //////////////////////////////////////////////////////////////////////////////// // No duplicates. -void Context::error (const std::string& input) -{ - if (input.length () && - std::find (errors.begin (), errors.end (), input) == errors.end ()) - errors.push_back (input); +void Context::error(const std::string& input) { + if (input.length() && std::find(errors.begin(), errors.end(), input) == errors.end()) + errors.push_back(input); } //////////////////////////////////////////////////////////////////////////////// -void Context::debug (const std::string& input) -{ - if (input.length ()) - debugMessages.push_back (input); +void Context::debug(const std::string& input) { + if (input.length()) debugMessages.push_back(input); } //////////////////////////////////////////////////////////////////////////////// -CurrentTask::CurrentTask (Context &context, const Task *task) - : context {context}, previous {context.currentTask} -{ +CurrentTask::CurrentTask(Context& context, const Task* task) + : context{context}, previous{context.currentTask} { context.currentTask = task; } //////////////////////////////////////////////////////////////////////////////// -CurrentTask::~CurrentTask () -{ - context.currentTask = previous; -} +CurrentTask::~CurrentTask() { context.currentTask = previous; } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/Context.h b/src/Context.h index 023178ccc..a456364e9 100644 --- a/src/Context.h +++ b/src/Context.h @@ -27,111 +27,111 @@ #ifndef INCLUDED_CONTEXT #define INCLUDED_CONTEXT -#include -#include -#include -#include -#include -#include -#include #include +#include +#include +#include +#include +#include +#include +#include #include + #include class CurrentTask; -class Context -{ -public: - Context () = default; // Default constructor - ~Context (); // Destructor +class Context { + public: + Context() = default; // Default constructor + ~Context(); // Destructor - Context (const Context&); - Context& operator= (const Context&); + Context(const Context &); + Context &operator=(const Context &); - static Context& getContext (); - static void setContext (Context*); + static Context &getContext(); + static void setContext(Context *); - int initialize (int, const char**); // all startup - int run (); - int dispatch (std::string&); // command handler dispatch + int initialize(int, const char **); // all startup + int run(); + int dispatch(std::string &); // command handler dispatch - int getWidth (); // determine terminal width - int getHeight (); // determine terminal height + int getWidth(); // determine terminal width + int getHeight(); // determine terminal height - std::string getTaskContext (const std::string&, std::string, bool fallback=true); + std::string getTaskContext(const std::string &, std::string, bool fallback = true); - const std::vector getColumns () const; - void getLimits (int&, int&); + const std::vector getColumns() const; + void getLimits(int &, int &); - bool color (); // TTY or ? - bool verbose (const std::string&); // Verbosity control + bool color(); // TTY or ? + bool verbose(const std::string &); // Verbosity control - void header (const std::string&); // Header message sink - void footnote (const std::string&); // Footnote message sink - void debug (const std::string&); // Debug message sink - void error (const std::string&); // Error message sink - non-maskable + void header(const std::string &); // Header message sink + void footnote(const std::string &); // Footnote message sink + void debug(const std::string &); // Debug message sink + void error(const std::string &); // Error message sink - non-maskable - void decomposeSortField (const std::string&, std::string&, bool&, bool&); - void debugTiming (const std::string&, const Timer&); + void decomposeSortField(const std::string &, std::string &, bool &, bool &); + void debugTiming(const std::string &, const Timer &); - CurrentTask withCurrentTask (const Task *); + CurrentTask withCurrentTask(const Task *); friend class CurrentTask; -private: - void staticInitialization (); - void createDefaultConfig (); - void updateXtermTitle (); - void updateVerbosity (); - void loadAliases (); - void propagateDebug (); + private: + void staticInitialization(); + void createDefaultConfig(); + void updateXtermTitle(); + void updateVerbosity(); + void loadAliases(); + void propagateDebug(); - static Context* context; + static Context *context; -public: - CLI2 cli2 {}; - std::string home_dir {}; - File rc_file {"~/.taskrc"}; - Path data_dir {"~/.task"}; - Configuration config {}; - TDB2 tdb2 {}; - Hooks hooks {}; - bool determine_color_use {true}; - bool use_color {true}; - bool verbosity_legacy {false}; - std::set verbosity {}; - std::vector headers {}; - std::vector footnotes {}; - std::vector errors {}; - std::vector debugMessages {}; - std::map commands {}; - std::map columns {}; - int terminal_width {0}; - int terminal_height {0}; + public: + CLI2 cli2{}; + std::string home_dir{}; + File rc_file{"~/.taskrc"}; + Path data_dir{"~/.task"}; + Configuration config{}; + TDB2 tdb2{}; + Hooks hooks{}; + bool determine_color_use{true}; + bool use_color{true}; + bool verbosity_legacy{false}; + std::set verbosity{}; + std::vector headers{}; + std::vector footnotes{}; + std::vector errors{}; + std::vector debugMessages{}; + std::map commands{}; + std::map columns{}; + int terminal_width{0}; + int terminal_height{0}; - Timer timer_total {}; - long time_total_us {0}; - long time_init_us {0}; - long time_load_us {0}; - long time_gc_us {0}; - long time_filter_us {0}; - long time_commit_us {0}; - long time_sort_us {0}; - long time_render_us {0}; - long time_hooks_us {0}; + Timer timer_total{}; + long time_total_us{0}; + long time_init_us{0}; + long time_load_us{0}; + long time_gc_us{0}; + long time_filter_us{0}; + long time_commit_us{0}; + long time_sort_us{0}; + long time_render_us{0}; + long time_hooks_us{0}; // the current task for DOM references, or NULL if there is no task - const Task * currentTask {NULL}; + const Task *currentTask{NULL}; }; //////////////////////////////////////////////////////////////////////////////// // CurrentTask resets Context::currentTask to previous context task on destruction; this ensures // that this context value is restored when exiting the scope where the context was applied. class CurrentTask { -public: + public: ~CurrentTask(); -private: + private: CurrentTask(Context &context, const Task *previous); Context &context; diff --git a/src/DOM.cpp b/src/DOM.cpp index e2eea1b68..fe47f2878 100644 --- a/src/DOM.cpp +++ b/src/DOM.cpp @@ -27,19 +27,20 @@ #include // cmake.h include header must come first -#include -#include -#include -#include -#include -#include #include +#include #include #include -#include +#include +#include #include +#include +#include #include +#include +#include + //////////////////////////////////////////////////////////////////////////////// // DOM Supported References: // @@ -62,23 +63,18 @@ // system.version // system.os // -bool getDOM (const std::string& name, Variant& value) -{ +bool getDOM(const std::string& name, Variant& value) { // Special case, blank refs cause problems. - if (name == "") - return false; + if (name == "") return false; - auto len = name.length (); + auto len = name.length(); // rc. --> context.config - if (len > 3 && - ! name.compare (0, 3, "rc.", 3)) - { - auto key = name.substr (3); - auto c = Context::getContext ().config.find (key); - if (c != Context::getContext ().config.end ()) - { - value = Variant (c->second); + if (len > 3 && !name.compare(0, 3, "rc.", 3)) { + auto key = name.substr(3); + auto c = Context::getContext().config.find(key); + if (c != Context::getContext().config.end()) { + value = Variant(c->second); return true; } @@ -86,55 +82,41 @@ bool getDOM (const std::string& name, Variant& value) } // tw.* - if (len > 3 && - ! name.compare (0, 3, "tw.", 3)) - { - if (name == "tw.syncneeded") - { - value = Variant (0); - if (Context::getContext ().tdb2.num_local_changes () > 0) { - value = Variant (1); + if (len > 3 && !name.compare(0, 3, "tw.", 3)) { + if (name == "tw.syncneeded") { + value = Variant(0); + if (Context::getContext().tdb2.num_local_changes() > 0) { + value = Variant(1); } return true; - } - else if (name == "tw.program") - { - value = Variant (Context::getContext ().cli2.getBinary ()); + } else if (name == "tw.program") { + value = Variant(Context::getContext().cli2.getBinary()); return true; - } - else if (name == "tw.args") - { + } else if (name == "tw.args") { std::string commandLine; - for (auto& arg : Context::getContext ().cli2._original_args) - { - if (commandLine != "") - commandLine += ' '; + for (auto& arg : Context::getContext().cli2._original_args) { + if (commandLine != "") commandLine += ' '; commandLine += arg.attribute("raw"); } - value = Variant (commandLine); + value = Variant(commandLine); return true; - } - else if (name == "tw.width") - { - value = Variant (static_cast (Context::getContext ().terminal_width - ? Context::getContext ().terminal_width - : Context::getContext ().getWidth ())); + } else if (name == "tw.width") { + value = Variant(static_cast(Context::getContext().terminal_width + ? Context::getContext().terminal_width + : Context::getContext().getWidth())); return true; - } - else if (name == "tw.height") - { - value = Variant (static_cast (Context::getContext ().terminal_height - ? Context::getContext ().terminal_height - : Context::getContext ().getHeight ())); + } else if (name == "tw.height") { + value = Variant(static_cast(Context::getContext().terminal_height + ? Context::getContext().terminal_height + : Context::getContext().getHeight())); return true; } - else if (name == "tw.version") - { - value = Variant (VERSION); + else if (name == "tw.version") { + value = Variant(VERSION); return true; } @@ -142,40 +124,29 @@ bool getDOM (const std::string& name, Variant& value) } // context.* - if (len > 8 && - ! name.compare (0, 8, "context.", 8)) - { - if (name == "context.program") - { - value = Variant (Context::getContext ().cli2.getBinary ()); + if (len > 8 && !name.compare(0, 8, "context.", 8)) { + if (name == "context.program") { + value = Variant(Context::getContext().cli2.getBinary()); return true; - } - else if (name == "context.args") - { + } else if (name == "context.args") { std::string commandLine; - for (auto& arg : Context::getContext ().cli2._original_args) - { - if (commandLine != "") - commandLine += ' '; + for (auto& arg : Context::getContext().cli2._original_args) { + if (commandLine != "") commandLine += ' '; commandLine += arg.attribute("raw"); } - value = Variant (commandLine); + value = Variant(commandLine); return true; - } - else if (name == "context.width") - { - value = Variant (static_cast (Context::getContext ().terminal_width - ? Context::getContext ().terminal_width - : Context::getContext ().getWidth ())); + } else if (name == "context.width") { + value = Variant(static_cast(Context::getContext().terminal_width + ? Context::getContext().terminal_width + : Context::getContext().getWidth())); return true; - } - else if (name == "context.height") - { - value = Variant (static_cast (Context::getContext ().terminal_height - ? Context::getContext ().terminal_height - : Context::getContext ().getHeight ())); + } else if (name == "context.height") { + value = Variant(static_cast(Context::getContext().terminal_height + ? Context::getContext().terminal_height + : Context::getContext().getHeight())); return true; } @@ -183,20 +154,16 @@ bool getDOM (const std::string& name, Variant& value) } // system. --> Implement locally. - if (len > 7 && - ! name.compare (0, 7, "system.", 7)) - { + if (len > 7 && !name.compare(0, 7, "system.", 7)) { // Taskwarrior version number. - if (name == "system.version") - { - value = Variant (VERSION); + if (name == "system.version") { + value = Variant(VERSION); return true; } // OS type. - else if (name == "system.os") - { - value = Variant (osName ()); + else if (name == "system.os") { + value = Variant(osName()); return true; } @@ -239,210 +206,192 @@ bool getDOM (const std::string& name, Variant& value) // // If task is NULL, then the contextual task will be determined from the DOM // string, if any exists. -bool getDOM (const std::string& name, const Task* task, Variant& value) -{ +bool getDOM(const std::string& name, const Task* task, Variant& value) { // Special case, blank refs cause problems. - if (name == "") - return false; + if (name == "") return false; // Quickly deal with the most common cases. - if (task && name == "id") - { - value = Variant (static_cast (task->id)); + if (task && name == "id") { + value = Variant(static_cast(task->id)); return true; } - if (task && name == "urgency") - { - value = Variant (task->urgency_c ()); + if (task && name == "urgency") { + value = Variant(task->urgency_c()); return true; } // split name on '.' - auto elements = split (name, '.'); + auto elements = split(name, '.'); Task loaded_task; // decide whether the reference is going to be the passed // "task" or whether it's going to be a newly loaded task (if id/uuid was // given). const Task* ref = task; - Lexer lexer (elements[0]); + Lexer lexer(elements[0]); std::string token; Lexer::Type type; // If this can be ID/UUID reference (the name contains '.'), // lex it to figure out. Otherwise don't lex, as lexing can be slow. - if ((elements.size() > 1) and lexer.token (token, type)) - { + if ((elements.size() > 1) and lexer.token(token, type)) { bool reloaded = false; - if (type == Lexer::Type::uuid && - token.length () == elements[0].length ()) - { - if (!task || token != task->get ("uuid")) - { - if (Context::getContext ().tdb2.get (token, loaded_task)) - reloaded = true; + if (type == Lexer::Type::uuid && token.length() == elements[0].length()) { + if (!task || token != task->get("uuid")) { + if (Context::getContext().tdb2.get(token, loaded_task)) reloaded = true; } // Eat elements[0]/UUID. - elements.erase (elements.begin ()); - } - else if (type == Lexer::Type::number && - token.find ('.') == std::string::npos) - { - auto id = strtol (token.c_str (), nullptr, 10); - if (id && (!task || id != task->id)) - { - if (Context::getContext ().tdb2.get (id, loaded_task)) - reloaded = true; + elements.erase(elements.begin()); + } else if (type == Lexer::Type::number && token.find('.') == std::string::npos) { + auto id = strtol(token.c_str(), nullptr, 10); + if (id && (!task || id != task->id)) { + if (Context::getContext().tdb2.get(id, loaded_task)) reloaded = true; } // Eat elements[0]/ID. - elements.erase (elements.begin ()); + elements.erase(elements.begin()); } - if (reloaded) - ref = &loaded_task; + if (reloaded) ref = &loaded_task; } - // The remainder of this method requires a contextual task, so if we do not // have one, delegate to the two-argument getDOM - if (!ref) - return getDOM (name, value); + if (!ref) return getDOM(name, value); - auto size = elements.size (); + auto size = elements.size(); std::string canonical; - if ((size == 1 || size == 2) && Context::getContext ().cli2.canonicalize (canonical, "attribute", elements[0])) - { + if ((size == 1 || size == 2) && + Context::getContext().cli2.canonicalize(canonical, "attribute", elements[0])) { // Now that 'ref' is the contextual task, and any ID/UUID is chopped off the // elements vector, DOM resolution is now simple. - if (size == 1 && canonical == "id") - { - value = Variant (static_cast (ref->id)); + if (size == 1 && canonical == "id") { + value = Variant(static_cast(ref->id)); return true; } - if (size == 1 && canonical == "urgency") - { - value = Variant (ref->urgency_c ()); + if (size == 1 && canonical == "urgency") { + value = Variant(ref->urgency_c()); return true; } // Special handling of status required for virtual waiting status // implementation. Remove in 3.0.0. - if (size == 1 && canonical == "status") - { - value = Variant (ref->statusToText (ref->getStatus ())); + if (size == 1 && canonical == "status") { + value = Variant(ref->statusToText(ref->getStatus())); return true; } - Column* column = Context::getContext ().columns[canonical]; + Column* column = Context::getContext().columns[canonical]; - if (size == 1 && column) - { - if (column->is_uda () && ! ref->has (canonical)) - { - value = Variant (""); + if (size == 1 && column) { + if (column->is_uda() && !ref->has(canonical)) { + value = Variant(""); return true; } - if (column->type () == "date") - { - auto numeric = ref->get_date (canonical); + if (column->type() == "date") { + auto numeric = ref->get_date(canonical); if (numeric == 0) - value = Variant (""); + value = Variant(""); else - value = Variant (numeric, Variant::type_date); - } - else if (column->type () == "duration" || canonical == "recur") - { - auto period = ref->get (canonical); + value = Variant(numeric, Variant::type_date); + } else if (column->type() == "duration" || canonical == "recur") { + auto period = ref->get(canonical); Duration iso; std::string::size_type cursor = 0; - if (iso.parse (period, cursor)) - value = Variant (iso.toTime_t (), Variant::type_duration); + if (iso.parse(period, cursor)) + value = Variant(iso.toTime_t(), Variant::type_duration); else - value = Variant (Duration (ref->get (canonical)).toTime_t (), Variant::type_duration); - } - else if (column->type () == "numeric") - value = Variant (ref->get_float (canonical)); + value = Variant(Duration(ref->get(canonical)).toTime_t(), Variant::type_duration); + } else if (column->type() == "numeric") + value = Variant(ref->get_float(canonical)); else - value = Variant (ref->get (canonical)); + value = Variant(ref->get(canonical)); return true; } - if (size == 2 && canonical == "tags") - { - value = Variant (ref->hasTag (elements[1]) ? elements[1] : ""); + if (size == 2 && canonical == "tags") { + value = Variant(ref->hasTag(elements[1]) ? elements[1] : ""); return true; } - if (size == 2 && column && column->type () == "date") - { - Datetime date (ref->get_date (canonical)); - if (elements[1] == "year") { value = Variant (static_cast (date.year ())); return true; } - else if (elements[1] == "month") { value = Variant (static_cast (date.month ())); return true; } - else if (elements[1] == "day") { value = Variant (static_cast (date.day ())); return true; } - else if (elements[1] == "week") { value = Variant (static_cast (date.week ())); return true; } - else if (elements[1] == "weekday") { value = Variant (static_cast (date.dayOfWeek ())); return true; } - else if (elements[1] == "julian") { value = Variant (static_cast (date.dayOfYear ())); return true; } - else if (elements[1] == "hour") { value = Variant (static_cast (date.hour ())); return true; } - else if (elements[1] == "minute") { value = Variant (static_cast (date.minute ())); return true; } - else if (elements[1] == "second") { value = Variant (static_cast (date.second ())); return true; } + if (size == 2 && column && column->type() == "date") { + Datetime date(ref->get_date(canonical)); + if (elements[1] == "year") { + value = Variant(static_cast(date.year())); + return true; + } else if (elements[1] == "month") { + value = Variant(static_cast(date.month())); + return true; + } else if (elements[1] == "day") { + value = Variant(static_cast(date.day())); + return true; + } else if (elements[1] == "week") { + value = Variant(static_cast(date.week())); + return true; + } else if (elements[1] == "weekday") { + value = Variant(static_cast(date.dayOfWeek())); + return true; + } else if (elements[1] == "julian") { + value = Variant(static_cast(date.dayOfYear())); + return true; + } else if (elements[1] == "hour") { + value = Variant(static_cast(date.hour())); + return true; + } else if (elements[1] == "minute") { + value = Variant(static_cast(date.minute())); + return true; + } else if (elements[1] == "second") { + value = Variant(static_cast(date.second())); + return true; + } } } - if (size == 2 && elements[0] == "annotations" && elements[1] == "count") - { - value = Variant (static_cast (ref->getAnnotationCount ())); + if (size == 2 && elements[0] == "annotations" && elements[1] == "count") { + value = Variant(static_cast(ref->getAnnotationCount())); return true; } - if (size == 3 && elements[0] == "annotations") - { - auto annos = ref->getAnnotations (); + if (size == 3 && elements[0] == "annotations") { + auto annos = ref->getAnnotations(); - int a = strtol (elements[1].c_str (), nullptr, 10); + int a = strtol(elements[1].c_str(), nullptr, 10); int count = 0; // Count off the 'a'th annotation. - for (const auto& i : annos) - { - if (++count == a) - { - if (elements[2] == "entry") - { + for (const auto& i : annos) { + if (++count == a) { + if (elements[2] == "entry") { // annotation_1234567890 // 0 ^11 - value = Variant ((time_t) strtoll (i.first.substr (11).c_str (), NULL, 10), Variant::type_date); + value = + Variant((time_t)strtoll(i.first.substr(11).c_str(), NULL, 10), Variant::type_date); return true; - } - else if (elements[2] == "description") - { - value = Variant (i.second); + } else if (elements[2] == "description") { + value = Variant(i.second); return true; } } } } - if (size == 4 && elements[0] == "annotations" && elements[2] == "entry") - { - auto annos = ref->getAnnotations (); + if (size == 4 && elements[0] == "annotations" && elements[2] == "entry") { + auto annos = ref->getAnnotations(); - int a = strtol (elements[1].c_str (), nullptr, 10); + int a = strtol(elements[1].c_str(), nullptr, 10); int count = 0; // Count off the 'a'th annotation. - for (const auto& i : annos) - { - if (++count == a) - { + for (const auto& i : annos) { + if (++count == a) { // ..entry.year // ..entry.month // ..entry.day @@ -452,22 +401,41 @@ bool getDOM (const std::string& name, const Task* task, Variant& value) // ..entry.hour // ..entry.minute // ..entry.second - Datetime date (i.first.substr (11)); - if (elements[3] == "year") { value = Variant (static_cast (date.year ())); return true; } - else if (elements[3] == "month") { value = Variant (static_cast (date.month ())); return true; } - else if (elements[3] == "day") { value = Variant (static_cast (date.day ())); return true; } - else if (elements[3] == "week") { value = Variant (static_cast (date.week ())); return true; } - else if (elements[3] == "weekday") { value = Variant (static_cast (date.dayOfWeek ())); return true; } - else if (elements[3] == "julian") { value = Variant (static_cast (date.dayOfYear ())); return true; } - else if (elements[3] == "hour") { value = Variant (static_cast (date.hour ())); return true; } - else if (elements[3] == "minute") { value = Variant (static_cast (date.minute ())); return true; } - else if (elements[3] == "second") { value = Variant (static_cast (date.second ())); return true; } + Datetime date(i.first.substr(11)); + if (elements[3] == "year") { + value = Variant(static_cast(date.year())); + return true; + } else if (elements[3] == "month") { + value = Variant(static_cast(date.month())); + return true; + } else if (elements[3] == "day") { + value = Variant(static_cast(date.day())); + return true; + } else if (elements[3] == "week") { + value = Variant(static_cast(date.week())); + return true; + } else if (elements[3] == "weekday") { + value = Variant(static_cast(date.dayOfWeek())); + return true; + } else if (elements[3] == "julian") { + value = Variant(static_cast(date.dayOfYear())); + return true; + } else if (elements[3] == "hour") { + value = Variant(static_cast(date.hour())); + return true; + } else if (elements[3] == "minute") { + value = Variant(static_cast(date.minute())); + return true; + } else if (elements[3] == "second") { + value = Variant(static_cast(date.second())); + return true; + } } } } // Delegate to the context-free version of DOM::get. - return getDOM (name, value); + return getDOM(name, value); } //////////////////////////////////////////////////////////////////////////////// @@ -513,41 +481,28 @@ bool getDOM (const std::string& name, const Task* task, Variant& value) // This makes the DOM class a reusible object. //////////////////////////////////////////////////////////////////////////////// -DOM::~DOM () -{ - delete _node; +DOM::~DOM() { delete _node; } + +//////////////////////////////////////////////////////////////////////////////// +void DOM::addSource(const std::string& reference, bool (*provider)(const std::string&, Variant&)) { + if (_node == nullptr) _node = new DOM::Node(); + + _node->addSource(reference, provider); } //////////////////////////////////////////////////////////////////////////////// -void DOM::addSource ( - const std::string& reference, - bool (*provider)(const std::string&, Variant&)) -{ - if (_node == nullptr) - _node = new DOM::Node (); - - _node->addSource (reference, provider); +bool DOM::valid(const std::string& reference) const { + return _node && _node->find(reference) != nullptr; } //////////////////////////////////////////////////////////////////////////////// -bool DOM::valid (const std::string& reference) const -{ - return _node && _node->find (reference) != nullptr; -} +Variant DOM::get(const std::string& reference) const { + Variant v(""); -//////////////////////////////////////////////////////////////////////////////// -Variant DOM::get (const std::string& reference) const -{ - Variant v (""); - - if (_node) - { - auto node = _node->find (reference); - if (node != nullptr && - node->_provider != nullptr) - { - if (node->_provider (reference, v)) - return v; + if (_node) { + auto node = _node->find(reference); + if (node != nullptr && node->_provider != nullptr) { + if (node->_provider(reference, v)) return v; } } @@ -555,60 +510,47 @@ Variant DOM::get (const std::string& reference) const } //////////////////////////////////////////////////////////////////////////////// -int DOM::count () const -{ - if (_node) - return _node->count (); +int DOM::count() const { + if (_node) return _node->count(); return 0; } //////////////////////////////////////////////////////////////////////////////// -std::vector DOM::decomposeReference (const std::string& reference) -{ - return split (reference, '.'); +std::vector DOM::decomposeReference(const std::string& reference) { + return split(reference, '.'); } //////////////////////////////////////////////////////////////////////////////// -std::string DOM::dump () const -{ - if (_node) - return _node->dump (); +std::string DOM::dump() const { + if (_node) return _node->dump(); return ""; } //////////////////////////////////////////////////////////////////////////////// -DOM::Node::~Node () -{ - for (auto& branch : _branches) - delete branch; +DOM::Node::~Node() { + for (auto& branch : _branches) delete branch; } //////////////////////////////////////////////////////////////////////////////// -void DOM::Node::addSource ( - const std::string& reference, - bool (*provider)(const std::string&, Variant&)) -{ +void DOM::Node::addSource(const std::string& reference, + bool (*provider)(const std::string&, Variant&)) { auto cursor = this; - for (const auto& element : DOM::decomposeReference (reference)) - { - auto found {false}; - for (auto& branch : cursor->_branches) - { - if (branch->_name == element) - { + for (const auto& element : DOM::decomposeReference(reference)) { + auto found{false}; + for (auto& branch : cursor->_branches) { + if (branch->_name == element) { cursor = branch; found = true; break; } } - if (! found) - { - auto branch = new DOM::Node (); + if (!found) { + auto branch = new DOM::Node(); branch->_name = element; - cursor->_branches.push_back (branch); + cursor->_branches.push_back(branch); cursor = branch; } } @@ -618,85 +560,66 @@ void DOM::Node::addSource ( //////////////////////////////////////////////////////////////////////////////// // A valid reference is one that has a provider function. -bool DOM::Node::valid (const std::string& reference) const -{ - return find (reference) != nullptr; -} +bool DOM::Node::valid(const std::string& reference) const { return find(reference) != nullptr; } //////////////////////////////////////////////////////////////////////////////// -const DOM::Node* DOM::Node::find (const std::string& reference) const -{ +const DOM::Node* DOM::Node::find(const std::string& reference) const { auto cursor = this; - for (const auto& element : DOM::decomposeReference (reference)) - { - auto found {false}; - for (auto& branch : cursor->_branches) - { - if (branch->_name == element) - { + for (const auto& element : DOM::decomposeReference(reference)) { + auto found{false}; + for (auto& branch : cursor->_branches) { + if (branch->_name == element) { cursor = branch; found = true; break; } } - if (! found) - break; + if (!found) break; } - if (reference.length () && cursor != this) - return cursor; + if (reference.length() && cursor != this) return cursor; return nullptr; } //////////////////////////////////////////////////////////////////////////////// -int DOM::Node::count () const -{ +int DOM::Node::count() const { // Recurse and count the branches. - int total {0}; - for (auto& branch : _branches) - { - if (branch->_provider) - ++total; - total += branch->count (); + int total{0}; + for (auto& branch : _branches) { + if (branch->_provider) ++total; + total += branch->count(); } return total; } //////////////////////////////////////////////////////////////////////////////// -std::string DOM::Node::dumpNode ( - const DOM::Node* node, - int depth) const -{ +std::string DOM::Node::dumpNode(const DOM::Node* node, int depth) const { std::stringstream out; // Indent. - out << std::string (depth * 2, ' '); + out << std::string(depth * 2, ' '); out << "\033[31m" << node->_name << "\033[0m"; - if (node->_provider) - out << " 0x" << std::hex << (long long) (void*) node->_provider; + if (node->_provider) out << " 0x" << std::hex << (long long)(void*)node->_provider; out << '\n'; // Recurse for branches. - for (auto& b : node->_branches) - out << dumpNode (b, depth + 1); + for (auto& b : node->_branches) out << dumpNode(b, depth + 1); - return out.str (); + return out.str(); } //////////////////////////////////////////////////////////////////////////////// -std::string DOM::Node::dump () const -{ +std::string DOM::Node::dump() const { std::stringstream out; - out << "DOM::Node (" << count () << " nodes)\n" - << dumpNode (this, 1); + out << "DOM::Node (" << count() << " nodes)\n" << dumpNode(this, 1); - return out.str (); + return out.str(); } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/DOM.h b/src/DOM.h index e3595e411..3c2bd3f79 100644 --- a/src/DOM.h +++ b/src/DOM.h @@ -27,49 +27,48 @@ #ifndef INCLUDED_DOM #define INCLUDED_DOM -#include -#include #include +#include + +#include // 2017-04-22 Deprecated, use DOM::get. -bool getDOM (const std::string&, Variant&); -bool getDOM (const std::string&, const Task*, Variant&); +bool getDOM(const std::string&, Variant&); +bool getDOM(const std::string&, const Task*, Variant&); -class DOM -{ -public: - ~DOM (); - void addSource (const std::string&, bool (*)(const std::string&, Variant&)); - bool valid (const std::string&) const; -/* - // TODO Task object should register a generic provider. - Variant get (const Task&, const std::string&) const; -*/ - Variant get (const std::string&) const; - int count () const; - static std::vector decomposeReference (const std::string&); - std::string dump () const; +class DOM { + public: + ~DOM(); + void addSource(const std::string&, bool (*)(const std::string&, Variant&)); + bool valid(const std::string&) const; + /* + // TODO Task object should register a generic provider. + Variant get (const Task&, const std::string&) const; + */ + Variant get(const std::string&) const; + int count() const; + static std::vector decomposeReference(const std::string&); + std::string dump() const; -private: - class Node - { - public: - ~Node (); - void addSource (const std::string&, bool (*)(const std::string&, Variant&)); - bool valid (const std::string&) const; - const DOM::Node* find (const std::string&) const; - int count () const; - std::string dumpNode (const DOM::Node*, int) const; - std::string dump () const; + private: + class Node { + public: + ~Node(); + void addSource(const std::string&, bool (*)(const std::string&, Variant&)); + bool valid(const std::string&) const; + const DOM::Node* find(const std::string&) const; + int count() const; + std::string dumpNode(const DOM::Node*, int) const; + std::string dump() const; - public: - std::string _name {"Unknown"}; - bool (*_provider)(const std::string&, Variant&) {nullptr}; - std::vector _branches {}; + public: + std::string _name{"Unknown"}; + bool (*_provider)(const std::string&, Variant&){nullptr}; + std::vector _branches{}; }; -private: - DOM::Node* _node {nullptr}; + private: + DOM::Node* _node{nullptr}; }; #endif diff --git a/src/Eval.cpp b/src/Eval.cpp index 9d2748aa3..5b869061e 100644 --- a/src/Eval.cpp +++ b/src/Eval.cpp @@ -27,75 +27,76 @@ #include // cmake.h include header must come first -#include -#include -#include -#include -#include -#include #include -#include +#include +#include +#include +#include #include +#include +#include + +#include //////////////////////////////////////////////////////////////////////////////// // Supported operators, borrowed from C++, particularly the precedence. // Note: table is sorted by length of operator string, so searches match // longest first. -static struct -{ +static struct { std::string op; - int precedence; - char type; // b=binary, u=unary, c=circumfix - char associativity; // l=left, r=right, _=? -} operators[] = -{ - // Operator Precedence Type Associativity - { "^", 16, 'b', 'r' }, // Exponent + int precedence; + char type; // b=binary, u=unary, c=circumfix + char associativity; // l=left, r=right, _=? +} operators[] = { + // Operator Precedence Type Associativity + {"^", 16, 'b', 'r'}, // Exponent - { "!", 15, 'u', 'r' }, // Unary not - { "_neg_", 15, 'u', 'r' }, // Unary minus - { "_pos_", 15, 'u', 'r' }, // Unary plus + {"!", 15, 'u', 'r'}, // Unary not + {"_neg_", 15, 'u', 'r'}, // Unary minus + {"_pos_", 15, 'u', 'r'}, // Unary plus - { "_hastag_", 14, 'b', 'l'}, // +tag [Pseudo-op] - { "_notag_", 14, 'b', 'l'}, // -tag [Pseudo-op] + {"_hastag_", 14, 'b', 'l'}, // +tag [Pseudo-op] + {"_notag_", 14, 'b', 'l'}, // -tag [Pseudo-op] - { "*", 13, 'b', 'l' }, // Multiplication - { "/", 13, 'b', 'l' }, // Division - { "%", 13, 'b', 'l' }, // Modulus + {"*", 13, 'b', 'l'}, // Multiplication + {"/", 13, 'b', 'l'}, // Division + {"%", 13, 'b', 'l'}, // Modulus - { "+", 12, 'b', 'l' }, // Addition - { "-", 12, 'b', 'l' }, // Subtraction + {"+", 12, 'b', 'l'}, // Addition + {"-", 12, 'b', 'l'}, // Subtraction - { "<=", 10, 'b', 'l' }, // Less than or equal - { ">=", 10, 'b', 'l' }, // Greater than or equal - { ">", 10, 'b', 'l' }, // Greater than - { "<", 10, 'b', 'l' }, // Less than + {"<=", 10, 'b', 'l'}, // Less than or equal + {">=", 10, 'b', 'l'}, // Greater than or equal + {">", 10, 'b', 'l'}, // Greater than + {"<", 10, 'b', 'l'}, // Less than - { "=", 9, 'b', 'l' }, // Equal (partial) - { "==", 9, 'b', 'l' }, // Equal (exact) - { "!=", 9, 'b', 'l' }, // Inequal (partial) - { "!==", 9, 'b', 'l' }, // Inequal (exact) + {"=", 9, 'b', 'l'}, // Equal (partial) + {"==", 9, 'b', 'l'}, // Equal (exact) + {"!=", 9, 'b', 'l'}, // Inequal (partial) + {"!==", 9, 'b', 'l'}, // Inequal (exact) - { "~", 8, 'b', 'l' }, // Regex match - { "!~", 8, 'b', 'l' }, // Regex non-match + {"~", 8, 'b', 'l'}, // Regex match + {"!~", 8, 'b', 'l'}, // Regex non-match - { "and", 5, 'b', 'l' }, // Conjunction - { "or", 4, 'b', 'l' }, // Disjunction - { "xor", 3, 'b', 'l' }, // Disjunction + {"and", 5, 'b', 'l'}, // Conjunction + {"or", 4, 'b', 'l'}, // Disjunction + {"xor", 3, 'b', 'l'}, // Disjunction - { "(", 0, 'c', '_' }, // Precedence start - { ")", 0, 'c', '_' }, // Precedence end + {"(", 0, 'c', '_'}, // Precedence start + {")", 0, 'c', '_'}, // Precedence end }; -#define NUM_OPERATORS (sizeof (operators) / sizeof (operators[0])) +#define NUM_OPERATORS (sizeof(operators) / sizeof(operators[0])) //////////////////////////////////////////////////////////////////////////////// // Built-in support for some named constants. -static bool namedConstants (const std::string& name, Variant& value) -{ - if (name == "true") value = Variant (true); - else if (name == "false") value = Variant (false); - else if (name == "pi") value = Variant (3.14159165); +static bool namedConstants(const std::string& name, Variant& value) { + if (name == "true") + value = Variant(true); + else if (name == "false") + value = Variant(false); + else if (name == "pi") + value = Variant(3.14159165); else return false; @@ -104,11 +105,9 @@ static bool namedConstants (const std::string& name, Variant& value) //////////////////////////////////////////////////////////////////////////////// // Support for evaluating DOM references (add with `e.AddSource(domSource)`) -bool domSource (const std::string& identifier, Variant& value) -{ - if (getDOM (identifier, Context::getContext ().currentTask, value)) - { - value.source (identifier); +bool domSource(const std::string& identifier, Variant& value) { + if (getDOM(identifier, Context::getContext().currentTask, value)) { + value.source(identifier); return true; } @@ -116,300 +115,273 @@ bool domSource (const std::string& identifier, Variant& value) } //////////////////////////////////////////////////////////////////////////////// -Eval::Eval () -{ - addSource (namedConstants); -} +Eval::Eval() { addSource(namedConstants); } //////////////////////////////////////////////////////////////////////////////// -void Eval::addSource (bool (*source)(const std::string&, Variant&)) -{ - _sources.push_back (source); -} +void Eval::addSource(bool (*source)(const std::string&, Variant&)) { _sources.push_back(source); } //////////////////////////////////////////////////////////////////////////////// -void Eval::evaluateInfixExpression (const std::string& e, Variant& v) const -{ +void Eval::evaluateInfixExpression(const std::string& e, Variant& v) const { // Reduce e to a vector of tokens. - Lexer l (e); - std::vector > tokens; + Lexer l(e); + std::vector> tokens; std::string token; Lexer::Type type; - while (l.token (token, type)) - tokens.emplace_back (token, type); + while (l.token(token, type)) tokens.emplace_back(token, type); // Parse for syntax checking and operator replacement. - if (_debug) - Context::getContext ().debug ("FILTER Infix " + dump (tokens)); - infixParse (tokens); - if (_debug) - Context::getContext ().debug ("FILTER Infix parsed " + dump (tokens)); + if (_debug) Context::getContext().debug("FILTER Infix " + dump(tokens)); + infixParse(tokens); + if (_debug) Context::getContext().debug("FILTER Infix parsed " + dump(tokens)); // Convert infix --> postfix. - infixToPostfix (tokens); - if (_debug) - Context::getContext ().debug ("FILTER Postfix " + dump (tokens)); + infixToPostfix(tokens); + if (_debug) Context::getContext().debug("FILTER Postfix " + dump(tokens)); // Call the postfix evaluator. - evaluatePostfixStack (tokens, v); + evaluatePostfixStack(tokens, v); } //////////////////////////////////////////////////////////////////////////////// -void Eval::evaluatePostfixExpression (const std::string& e, Variant& v) const -{ +void Eval::evaluatePostfixExpression(const std::string& e, Variant& v) const { // Reduce e to a vector of tokens. - Lexer l (e); - std::vector > tokens; + Lexer l(e); + std::vector> tokens; std::string token; Lexer::Type type; - while (l.token (token, type)) - tokens.emplace_back (token, type); + while (l.token(token, type)) tokens.emplace_back(token, type); - if (_debug) - Context::getContext ().debug ("FILTER Postfix " + dump (tokens)); + if (_debug) Context::getContext().debug("FILTER Postfix " + dump(tokens)); // Call the postfix evaluator. - evaluatePostfixStack (tokens, v); + evaluatePostfixStack(tokens, v); } //////////////////////////////////////////////////////////////////////////////// -void Eval::compileExpression ( - const std::vector >& precompiled) -{ +void Eval::compileExpression(const std::vector>& precompiled) { _compiled = precompiled; // Parse for syntax checking and operator replacement. - if (_debug) - Context::getContext ().debug ("FILTER Infix " + dump (_compiled)); - infixParse (_compiled); - if (_debug) - Context::getContext ().debug ("FILTER Infix parsed " + dump (_compiled)); + if (_debug) Context::getContext().debug("FILTER Infix " + dump(_compiled)); + infixParse(_compiled); + if (_debug) Context::getContext().debug("FILTER Infix parsed " + dump(_compiled)); // Convert infix --> postfix. - infixToPostfix (_compiled); - if (_debug) - Context::getContext ().debug ("FILTER Postfix " + dump (_compiled)); + infixToPostfix(_compiled); + if (_debug) Context::getContext().debug("FILTER Postfix " + dump(_compiled)); } //////////////////////////////////////////////////////////////////////////////// -void Eval::evaluateCompiledExpression (Variant& v) -{ +void Eval::evaluateCompiledExpression(Variant& v) { // Call the postfix evaluator. - evaluatePostfixStack (_compiled, v); + evaluatePostfixStack(_compiled, v); } //////////////////////////////////////////////////////////////////////////////// -void Eval::debug (bool value) -{ - _debug = value; -} +void Eval::debug(bool value) { _debug = value; } //////////////////////////////////////////////////////////////////////////////// // Static. -std::vector Eval::getOperators () -{ - std::vector all; +std::vector Eval::getOperators() { + std::vector all; all.reserve(NUM_OPERATORS); - for (const auto &opr : operators) - all.push_back (opr.op); + for (const auto& opr : operators) all.push_back(opr.op); return all; } //////////////////////////////////////////////////////////////////////////////// // Static. -std::vector Eval::getBinaryOperators () -{ - std::vector all; - for (const auto &opr : operators) - if (opr.type == 'b') - all.push_back (opr.op); +std::vector Eval::getBinaryOperators() { + std::vector all; + for (const auto& opr : operators) + if (opr.type == 'b') all.push_back(opr.op); return all; } //////////////////////////////////////////////////////////////////////////////// -void Eval::evaluatePostfixStack ( - const std::vector >& tokens, - Variant& result) const -{ - if (tokens.size () == 0) - throw std::string ("No expression to evaluate."); +void Eval::evaluatePostfixStack(const std::vector>& tokens, + Variant& result) const { + if (tokens.size() == 0) throw std::string("No expression to evaluate."); // This is stack used by the postfix evaluator. - std::vector values; + std::vector values; values.reserve(tokens.size()); - for (const auto& token : tokens) - { + for (const auto& token : tokens) { // Unary operators. - if (token.second == Lexer::Type::op && - token.first == "!") - { - if (values.size () < 1) - throw std::string ("The expression could not be evaluated."); + if (token.second == Lexer::Type::op && token.first == "!") { + if (values.size() < 1) throw std::string("The expression could not be evaluated."); - Variant right = values.back (); - values.pop_back (); - Variant result = ! right; - values.push_back (result); + Variant right = values.back(); + values.pop_back(); + Variant result = !right; + values.push_back(result); if (_debug) - Context::getContext ().debug (format ("Eval {1} ↓'{2}' → ↑'{3}'", token.first, (std::string) right, (std::string) result)); - } - else if (token.second == Lexer::Type::op && - token.first == "_neg_") - { - if (values.size () < 1) - throw std::string ("The expression could not be evaluated."); + Context::getContext().debug(format("Eval {1} ↓'{2}' → ↑'{3}'", token.first, + (std::string)right, (std::string)result)); + } else if (token.second == Lexer::Type::op && token.first == "_neg_") { + if (values.size() < 1) throw std::string("The expression could not be evaluated."); - Variant right = values.back (); - values.pop_back (); + Variant right = values.back(); + values.pop_back(); - Variant result (0); + Variant result(0); result -= right; - values.push_back (result); + values.push_back(result); if (_debug) - Context::getContext ().debug (format ("Eval {1} ↓'{2}' → ↑'{3}'", token.first, (std::string) right, (std::string) result)); - } - else if (token.second == Lexer::Type::op && - token.first == "_pos_") - { + Context::getContext().debug(format("Eval {1} ↓'{2}' → ↑'{3}'", token.first, + (std::string)right, (std::string)result)); + } else if (token.second == Lexer::Type::op && token.first == "_pos_") { // The _pos_ operator is a NOP. if (_debug) - Context::getContext ().debug (format ("[{1}] eval op {2} NOP", values.size (), token.first)); + Context::getContext().debug(format("[{1}] eval op {2} NOP", values.size(), token.first)); } // Binary operators. - else if (token.second == Lexer::Type::op) - { - if (values.size () < 2) - throw std::string ("The expression could not be evaluated."); + else if (token.second == Lexer::Type::op) { + if (values.size() < 2) throw std::string("The expression could not be evaluated."); - Variant right = values.back (); - values.pop_back (); + Variant right = values.back(); + values.pop_back(); - Variant left = values.back (); - values.pop_back (); + Variant left = values.back(); + values.pop_back(); - auto contextTask = Context::getContext ().currentTask; + auto contextTask = Context::getContext().currentTask; // Ordering these by anticipation frequency of use is a good idea. Variant result; - if (token.first == "and") result = left && right; - else if (token.first == "or") result = left || right; - else if (token.first == "&&") result = left && right; - else if (token.first == "||") result = left || right; - else if (token.first == "<") result = left < right; - else if (token.first == "<=") result = left <= right; - else if (token.first == ">") result = left > right; - else if (token.first == ">=") result = left >= right; - else if (token.first == "==") result = left.operator== (right); - else if (token.first == "!==") result = left.operator!= (right); - else if (token.first == "=") result = left.operator_partial (right); - else if (token.first == "!=") result = left.operator_nopartial (right); - else if (token.first == "+") result = left + right; - else if (token.first == "-") result = left - right; - else if (token.first == "*") result = left * right; - else if (token.first == "/") result = left / right; - else if (token.first == "^") result = left ^ right; - else if (token.first == "%") result = left % right; - else if (token.first == "xor") result = left.operator_xor (right); + if (token.first == "and") + result = left && right; + else if (token.first == "or") + result = left || right; + else if (token.first == "&&") + result = left && right; + else if (token.first == "||") + result = left || right; + else if (token.first == "<") + result = left < right; + else if (token.first == "<=") + result = left <= right; + else if (token.first == ">") + result = left > right; + else if (token.first == ">=") + result = left >= right; + else if (token.first == "==") + result = left.operator==(right); + else if (token.first == "!==") + result = left.operator!=(right); + else if (token.first == "=") + result = left.operator_partial(right); + else if (token.first == "!=") + result = left.operator_nopartial(right); + else if (token.first == "+") + result = left + right; + else if (token.first == "-") + result = left - right; + else if (token.first == "*") + result = left * right; + else if (token.first == "/") + result = left / right; + else if (token.first == "^") + result = left ^ right; + else if (token.first == "%") + result = left % right; + else if (token.first == "xor") + result = left.operator_xor(right); else if (contextTask) { - if (token.first == "~") result = left.operator_match (right, *contextTask); - else if (token.first == "!~") result = left.operator_nomatch (right, *contextTask); - else if (token.first == "_hastag_") result = left.operator_hastag (right, *contextTask); - else if (token.first == "_notag_") result = left.operator_notag (right, *contextTask); + if (token.first == "~") + result = left.operator_match(right, *contextTask); + else if (token.first == "!~") + result = left.operator_nomatch(right, *contextTask); + else if (token.first == "_hastag_") + result = left.operator_hastag(right, *contextTask); + else if (token.first == "_notag_") + result = left.operator_notag(right, *contextTask); else - throw format ("Unsupported operator '{1}'.", token.first); - } - else - throw format ("Unsupported operator '{1}'.", token.first); + throw format("Unsupported operator '{1}'.", token.first); + } else + throw format("Unsupported operator '{1}'.", token.first); - values.push_back (result); + values.push_back(result); if (_debug) - Context::getContext ().debug (format ("Eval ↓'{1}' {2} ↓'{3}' → ↑'{4}'", (std::string) left, token.first, (std::string) right, (std::string) result)); + Context::getContext().debug(format("Eval ↓'{1}' {2} ↓'{3}' → ↑'{4}'", (std::string)left, + token.first, (std::string)right, (std::string)result)); } // Literals and identifiers. - else - { - Variant v (token.first); - switch (token.second) - { - case Lexer::Type::number: - if (Lexer::isAllDigits (token.first)) - { - v.cast (Variant::type_integer); - if (_debug) - Context::getContext ().debug (format ("Eval literal number ↑'{1}'", (std::string) v)); - } - else - { - v.cast (Variant::type_real); - if (_debug) - Context::getContext ().debug (format ("Eval literal decimal ↑'{1}'", (std::string) v)); - } - break; + else { + Variant v(token.first); + switch (token.second) { + case Lexer::Type::number: + if (Lexer::isAllDigits(token.first)) { + v.cast(Variant::type_integer); + if (_debug) + Context::getContext().debug(format("Eval literal number ↑'{1}'", (std::string)v)); + } else { + v.cast(Variant::type_real); + if (_debug) + Context::getContext().debug(format("Eval literal decimal ↑'{1}'", (std::string)v)); + } + break; - case Lexer::Type::op: - throw std::string ("Operator expected."); - break; + case Lexer::Type::op: + throw std::string("Operator expected."); + break; - case Lexer::Type::dom: - case Lexer::Type::identifier: - { + case Lexer::Type::dom: + case Lexer::Type::identifier: { bool found = false; - for (const auto& source : _sources) - { - if (source (token.first, v)) - { + for (const auto& source : _sources) { + if (source(token.first, v)) { if (_debug) - Context::getContext ().debug (format ("Eval identifier source '{1}' → ↑'{2}'", token.first, (std::string) v)); + Context::getContext().debug( + format("Eval identifier source '{1}' → ↑'{2}'", token.first, (std::string)v)); found = true; break; } } // An identifier that fails lookup is a string. - if (! found) - { - v.cast (Variant::type_string); + if (!found) { + v.cast(Variant::type_string); if (_debug) - Context::getContext ().debug (format ("Eval identifier source failed '{1}'", token.first)); + Context::getContext().debug( + format("Eval identifier source failed '{1}'", token.first)); } - } - break; + } break; - case Lexer::Type::date: - v.cast (Variant::type_date); - if (_debug) - Context::getContext ().debug (format ("Eval literal date ↑'{1}'", (std::string) v)); - break; + case Lexer::Type::date: + v.cast(Variant::type_date); + if (_debug) + Context::getContext().debug(format("Eval literal date ↑'{1}'", (std::string)v)); + break; - case Lexer::Type::duration: - v.cast (Variant::type_duration); - if (_debug) - Context::getContext ().debug (format ("Eval literal duration ↑'{1}'", (std::string) v)); - break; + case Lexer::Type::duration: + v.cast(Variant::type_duration); + if (_debug) + Context::getContext().debug(format("Eval literal duration ↑'{1}'", (std::string)v)); + break; - // Nothing to do. - case Lexer::Type::string: - default: - if (_debug) - Context::getContext ().debug (format ("Eval literal string ↑'{1}'", (std::string) v)); - break; + // Nothing to do. + case Lexer::Type::string: + default: + if (_debug) + Context::getContext().debug(format("Eval literal string ↑'{1}'", (std::string)v)); + break; } - values.push_back (v); + values.push_back(v); } } // If there is more than one variant left on the stack, then the original // expression was not valid. - if (values.size () != 1) - throw std::string ("The value is not an expression."); + if (values.size() != 1) throw std::string("The value is not an expression."); result = values[0]; } @@ -428,31 +400,20 @@ void Eval::evaluatePostfixStack ( // Exponent --> Primitive ["^" Primitive] // Primitive --> "(" Logical ")" | Variant // -void Eval::infixParse ( - std::vector >& infix) const -{ +void Eval::infixParse(std::vector>& infix) const { unsigned int i = 0; - parseLogical (infix, i); + parseLogical(infix, i); } //////////////////////////////////////////////////////////////////////////////// // Logical --> Regex {( "and" | "or" | "xor" ) Regex} -bool Eval::parseLogical ( - std::vector >& infix, - unsigned int &i) const -{ - if (i < infix.size () && - parseRegex (infix, i)) - { - while (i < infix.size () && - infix[i].second == Lexer::Type::op && - (infix[i].first == "and" || - infix[i].first == "or" || - infix[i].first == "xor")) - { +bool Eval::parseLogical(std::vector>& infix, + unsigned int& i) const { + if (i < infix.size() && parseRegex(infix, i)) { + while (i < infix.size() && infix[i].second == Lexer::Type::op && + (infix[i].first == "and" || infix[i].first == "or" || infix[i].first == "xor")) { ++i; - if (! parseRegex (infix, i)) - return false; + if (!parseRegex(infix, i)) return false; } return true; @@ -463,21 +424,13 @@ bool Eval::parseLogical ( //////////////////////////////////////////////////////////////////////////////// // Regex --> Equality {( "~" | "!~" ) Equality} -bool Eval::parseRegex ( - std::vector >& infix, - unsigned int &i) const -{ - if (i < infix.size () && - parseEquality (infix, i)) - { - while (i < infix.size () && - infix[i].second == Lexer::Type::op && - (infix[i].first == "~" || - infix[i].first == "!~")) - { +bool Eval::parseRegex(std::vector>& infix, + unsigned int& i) const { + if (i < infix.size() && parseEquality(infix, i)) { + while (i < infix.size() && infix[i].second == Lexer::Type::op && + (infix[i].first == "~" || infix[i].first == "!~")) { ++i; - if (! parseEquality (infix, i)) - return false; + if (!parseEquality(infix, i)) return false; } return true; @@ -488,23 +441,14 @@ bool Eval::parseRegex ( //////////////////////////////////////////////////////////////////////////////// // Equality --> Comparative {( "==" | "=" | "!==" | "!=" ) Comparative} -bool Eval::parseEquality ( - std::vector >& infix, - unsigned int &i) const -{ - if (i < infix.size () && - parseComparative (infix, i)) - { - while (i < infix.size () && - infix[i].second == Lexer::Type::op && - (infix[i].first == "==" || - infix[i].first == "=" || - infix[i].first == "!==" || - infix[i].first == "!=")) - { +bool Eval::parseEquality(std::vector>& infix, + unsigned int& i) const { + if (i < infix.size() && parseComparative(infix, i)) { + while (i < infix.size() && infix[i].second == Lexer::Type::op && + (infix[i].first == "==" || infix[i].first == "=" || infix[i].first == "!==" || + infix[i].first == "!=")) { ++i; - if (! parseComparative (infix, i)) - return false; + if (!parseComparative(infix, i)) return false; } return true; @@ -515,23 +459,14 @@ bool Eval::parseEquality ( //////////////////////////////////////////////////////////////////////////////// // Comparative --> Arithmetic {( "<=" | "<" | ">=" | ">" ) Arithmetic} -bool Eval::parseComparative ( - std::vector >& infix, - unsigned int &i) const -{ - if (i < infix.size () && - parseArithmetic (infix, i)) - { - while (i < infix.size () && - infix[i].second == Lexer::Type::op && - (infix[i].first == "<=" || - infix[i].first == "<" || - infix[i].first == ">=" || - infix[i].first == ">")) - { +bool Eval::parseComparative(std::vector>& infix, + unsigned int& i) const { + if (i < infix.size() && parseArithmetic(infix, i)) { + while (i < infix.size() && infix[i].second == Lexer::Type::op && + (infix[i].first == "<=" || infix[i].first == "<" || infix[i].first == ">=" || + infix[i].first == ">")) { ++i; - if (! parseArithmetic (infix, i)) - return false; + if (!parseArithmetic(infix, i)) return false; } return true; @@ -542,21 +477,13 @@ bool Eval::parseComparative ( //////////////////////////////////////////////////////////////////////////////// // Arithmetic --> Geometric {( "+" | "-" ) Geometric} -bool Eval::parseArithmetic ( - std::vector >& infix, - unsigned int &i) const -{ - if (i < infix.size () && - parseGeometric (infix, i)) - { - while (i < infix.size () && - infix[i].second == Lexer::Type::op && - (infix[i].first == "+" || - infix[i].first == "-")) - { +bool Eval::parseArithmetic(std::vector>& infix, + unsigned int& i) const { + if (i < infix.size() && parseGeometric(infix, i)) { + while (i < infix.size() && infix[i].second == Lexer::Type::op && + (infix[i].first == "+" || infix[i].first == "-")) { ++i; - if (! parseGeometric (infix, i)) - return false; + if (!parseGeometric(infix, i)) return false; } return true; @@ -567,22 +494,13 @@ bool Eval::parseArithmetic ( //////////////////////////////////////////////////////////////////////////////// // Geometric --> Tag {( "*" | "/" | "%" ) Tag} -bool Eval::parseGeometric ( - std::vector >& infix, - unsigned int &i) const -{ - if (i < infix.size () && - parseTag (infix, i)) - { - while (i < infix.size () && - infix[i].second == Lexer::Type::op && - (infix[i].first == "*" || - infix[i].first == "/" || - infix[i].first == "%")) - { +bool Eval::parseGeometric(std::vector>& infix, + unsigned int& i) const { + if (i < infix.size() && parseTag(infix, i)) { + while (i < infix.size() && infix[i].second == Lexer::Type::op && + (infix[i].first == "*" || infix[i].first == "/" || infix[i].first == "%")) { ++i; - if (! parseTag (infix, i)) - return false; + if (!parseTag(infix, i)) return false; } return true; @@ -593,21 +511,13 @@ bool Eval::parseGeometric ( //////////////////////////////////////////////////////////////////////////////// // Tag --> Unary {( "_hastag_" | "_notag_" ) Unary} -bool Eval::parseTag ( - std::vector >& infix, - unsigned int &i) const -{ - if (i < infix.size () && - parseUnary (infix, i)) - { - while (i < infix.size () && - infix[i].second == Lexer::Type::op && - (infix[i].first == "_hastag_" || - infix[i].first == "_notag_")) - { +bool Eval::parseTag(std::vector>& infix, + unsigned int& i) const { + if (i < infix.size() && parseUnary(infix, i)) { + while (i < infix.size() && infix[i].second == Lexer::Type::op && + (infix[i].first == "_hastag_" || infix[i].first == "_notag_")) { ++i; - if (! parseUnary (infix, i)) - return false; + if (!parseUnary(infix, i)) return false; } return true; @@ -618,47 +528,31 @@ bool Eval::parseTag ( //////////////////////////////////////////////////////////////////////////////// // Unary --> [( "-" | "+" | "!" )] Exponent -bool Eval::parseUnary ( - std::vector >& infix, - unsigned int &i) const -{ - if (i < infix.size ()) - { - if (infix[i].first == "-") - { +bool Eval::parseUnary(std::vector>& infix, + unsigned int& i) const { + if (i < infix.size()) { + if (infix[i].first == "-") { infix[i].first = "_neg_"; ++i; - } - else if (infix[i].first == "+") - { + } else if (infix[i].first == "+") { infix[i].first = "_pos_"; ++i; - } - else if (infix[i].first == "!") - { + } else if (infix[i].first == "!") { ++i; } } - return parseExponent (infix, i); + return parseExponent(infix, i); } //////////////////////////////////////////////////////////////////////////////// // Exponent --> Primitive ["^" Primitive] -bool Eval::parseExponent ( - std::vector >& infix, - unsigned int& i) const -{ - if (i < infix.size () && - parsePrimitive (infix, i)) - { - while (i < infix.size () && - infix[i].second == Lexer::Type::op && - infix[i].first == "^") - { +bool Eval::parseExponent(std::vector>& infix, + unsigned int& i) const { + if (i < infix.size() && parsePrimitive(infix, i)) { + while (i < infix.size() && infix[i].second == Lexer::Type::op && infix[i].first == "^") { ++i; - if (! parsePrimitive (infix, i)) - return false; + if (!parsePrimitive(infix, i)) return false; } return true; @@ -669,46 +563,31 @@ bool Eval::parseExponent ( //////////////////////////////////////////////////////////////////////////////// // Primitive --> "(" Logical ")" | Variant -bool Eval::parsePrimitive ( - std::vector >& infix, - unsigned int &i) const -{ - if (i < infix.size ()) - { - if (infix[i].first == "(") - { +bool Eval::parsePrimitive(std::vector>& infix, + unsigned int& i) const { + if (i < infix.size()) { + if (infix[i].first == "(") { ++i; - if (i < infix.size () && - parseLogical (infix, i)) - { - if (i < infix.size () && - infix[i].first == ")") - { + if (i < infix.size() && parseLogical(infix, i)) { + if (i < infix.size() && infix[i].first == ")") { ++i; return true; } } - } - else - { + } else { bool found = false; - for (const auto& source : _sources) - { + for (const auto& source : _sources) { Variant v; - if (source (infix[i].first, v)) - { + if (source(infix[i].first, v)) { found = true; break; } } - if (found) - { + if (found) { ++i; return true; - } - else if (infix[i].second != Lexer::Type::op) - { + } else if (infix[i].second != Lexer::Type::op) { ++i; return true; } @@ -750,95 +629,71 @@ bool Eval::parsePrimitive ( // Pop the operator onto the output queue. // Exit. // -void Eval::infixToPostfix ( - std::vector >& infix) const -{ +void Eval::infixToPostfix(std::vector>& infix) const { // Short circuit. - if (infix.size () == 1) - return; + if (infix.size() == 1) return; // Result. - std::vector > postfix; + std::vector> postfix; // Shunting yard. - std::vector > op_stack; + std::vector> op_stack; // Operator characteristics. char type; unsigned int precedence; char associativity; - for (auto& token : infix) - { - if (token.second == Lexer::Type::op && - token.first == "(") - { - op_stack.push_back (token); - } - else if (token.second == Lexer::Type::op && - token.first == ")") - { - while (op_stack.size () && - op_stack.back ().first != "(") - { - postfix.push_back (op_stack.back ()); - op_stack.pop_back (); + for (auto& token : infix) { + if (token.second == Lexer::Type::op && token.first == "(") { + op_stack.push_back(token); + } else if (token.second == Lexer::Type::op && token.first == ")") { + while (op_stack.size() && op_stack.back().first != "(") { + postfix.push_back(op_stack.back()); + op_stack.pop_back(); } - if (op_stack.size ()) - op_stack.pop_back (); + if (op_stack.size()) + op_stack.pop_back(); else - throw std::string ("Mismatched parentheses in expression"); - } - else if (token.second == Lexer::Type::op && - identifyOperator (token.first, type, precedence, associativity)) - { + throw std::string("Mismatched parentheses in expression"); + } else if (token.second == Lexer::Type::op && + identifyOperator(token.first, type, precedence, associativity)) { char type2; unsigned int precedence2; char associativity2; - while (op_stack.size () > 0 && - identifyOperator (op_stack.back ().first, type2, precedence2, associativity2) && + while (op_stack.size() > 0 && + identifyOperator(op_stack.back().first, type2, precedence2, associativity2) && ((associativity == 'l' && precedence <= precedence2) || - (associativity == 'r' && precedence < precedence2))) - { - postfix.push_back (op_stack.back ()); - op_stack.pop_back (); + (associativity == 'r' && precedence < precedence2))) { + postfix.push_back(op_stack.back()); + op_stack.pop_back(); } - op_stack.push_back (token); - } - else - { - postfix.push_back (token); + op_stack.push_back(token); + } else { + postfix.push_back(token); } } - while (op_stack.size ()) - { - if (op_stack.back ().first == "(" || - op_stack.back ().first == ")") - throw std::string ("Mismatched parentheses in expression"); + while (op_stack.size()) { + if (op_stack.back().first == "(" || op_stack.back().first == ")") + throw std::string("Mismatched parentheses in expression"); - postfix.push_back (op_stack.back ()); - op_stack.pop_back (); + postfix.push_back(op_stack.back()); + op_stack.pop_back(); } infix = postfix; } //////////////////////////////////////////////////////////////////////////////// -bool Eval::identifyOperator ( - const std::string& op, - char& type, - unsigned int& precedence, - char& associativity) const -{ - for (const auto& opr : operators) - { - if (opr.op == op) - { - type = opr.type; - precedence = opr.precedence; +bool Eval::identifyOperator(const std::string& op, char& type, unsigned int& precedence, + char& associativity) const { + for (const auto& opr : operators) { + if (opr.op == op) { + type = opr.type; + precedence = opr.precedence; associativity = opr.associativity; return true; } @@ -848,33 +703,29 @@ bool Eval::identifyOperator ( } //////////////////////////////////////////////////////////////////////////////// -std::string Eval::dump ( - std::vector >& tokens) const -{ +std::string Eval::dump(std::vector>& tokens) const { // Set up a color mapping. - std::map color_map; - color_map[Lexer::Type::op] = Color ("gray14 on gray6"); - color_map[Lexer::Type::number] = Color ("rgb530 on gray6"); - color_map[Lexer::Type::hex] = Color ("rgb303 on gray6"); - color_map[Lexer::Type::string] = Color ("rgb550 on gray6"); - color_map[Lexer::Type::dom] = Color ("rgb045 on gray6"); - color_map[Lexer::Type::identifier] = Color ("rgb035 on gray6"); - color_map[Lexer::Type::date] = Color ("rgb150 on gray6"); - color_map[Lexer::Type::duration] = Color ("rgb531 on gray6"); + std::map color_map; + color_map[Lexer::Type::op] = Color("gray14 on gray6"); + color_map[Lexer::Type::number] = Color("rgb530 on gray6"); + color_map[Lexer::Type::hex] = Color("rgb303 on gray6"); + color_map[Lexer::Type::string] = Color("rgb550 on gray6"); + color_map[Lexer::Type::dom] = Color("rgb045 on gray6"); + color_map[Lexer::Type::identifier] = Color("rgb035 on gray6"); + color_map[Lexer::Type::date] = Color("rgb150 on gray6"); + color_map[Lexer::Type::duration] = Color("rgb531 on gray6"); std::string output; - for (auto i = tokens.begin (); i != tokens.end (); ++i) - { - if (i != tokens.begin ()) - output += ' '; + for (auto i = tokens.begin(); i != tokens.end(); ++i) { + if (i != tokens.begin()) output += ' '; Color c; - if (color_map[i->second].nontrivial ()) + if (color_map[i->second].nontrivial()) c = color_map[i->second]; else - c = Color ("rgb000 on gray6"); + c = Color("rgb000 on gray6"); - output += c.colorize (i->first); + output += c.colorize(i->first); } return output; diff --git a/src/Eval.h b/src/Eval.h index 190d357b1..3203e8a15 100644 --- a/src/Eval.h +++ b/src/Eval.h @@ -27,50 +27,51 @@ #ifndef INCLUDED_EVAL #define INCLUDED_EVAL -#include -#include #include #include -bool domSource (const std::string&, Variant&); +#include +#include -class Eval -{ -public: - Eval (); +bool domSource(const std::string &, Variant &); - void addSource (bool (*fn)(const std::string&, Variant&)); - void evaluateInfixExpression (const std::string&, Variant&) const; - void evaluatePostfixExpression (const std::string&, Variant&) const; - void compileExpression (const std::vector >&); - void evaluateCompiledExpression (Variant&); - void debug (bool); +class Eval { + public: + Eval(); - static std::vector getOperators (); - static std::vector getBinaryOperators (); + void addSource(bool (*fn)(const std::string &, Variant &)); + void evaluateInfixExpression(const std::string &, Variant &) const; + void evaluatePostfixExpression(const std::string &, Variant &) const; + void compileExpression(const std::vector> &); + void evaluateCompiledExpression(Variant &); + void debug(bool); -private: - void evaluatePostfixStack (const std::vector >&, Variant&) const; - void infixToPostfix (std::vector >&) const; - void infixParse (std::vector >&) const; - bool parseLogical (std::vector >&, unsigned int &) const; - bool parseRegex (std::vector >&, unsigned int &) const; - bool parseEquality (std::vector >&, unsigned int &) const; - bool parseComparative (std::vector >&, unsigned int &) const; - bool parseArithmetic (std::vector >&, unsigned int &) const; - bool parseGeometric (std::vector >&, unsigned int &) const; - bool parseTag (std::vector >&, unsigned int &) const; - bool parseUnary (std::vector >&, unsigned int &) const; - bool parseExponent (std::vector >&, unsigned int &) const; - bool parsePrimitive (std::vector >&, unsigned int &) const; - bool identifyOperator (const std::string&, char&, unsigned int&, char&) const; + static std::vector getOperators(); + static std::vector getBinaryOperators(); - std::string dump (std::vector >&) const; + private: + void evaluatePostfixStack(const std::vector> &, + Variant &) const; + void infixToPostfix(std::vector> &) const; + void infixParse(std::vector> &) const; + bool parseLogical(std::vector> &, unsigned int &) const; + bool parseRegex(std::vector> &, unsigned int &) const; + bool parseEquality(std::vector> &, unsigned int &) const; + bool parseComparative(std::vector> &, unsigned int &) const; + bool parseArithmetic(std::vector> &, unsigned int &) const; + bool parseGeometric(std::vector> &, unsigned int &) const; + bool parseTag(std::vector> &, unsigned int &) const; + bool parseUnary(std::vector> &, unsigned int &) const; + bool parseExponent(std::vector> &, unsigned int &) const; + bool parsePrimitive(std::vector> &, unsigned int &) const; + bool identifyOperator(const std::string &, char &, unsigned int &, char &) const; -private: - std::vector _sources {}; - bool _debug {false}; - std::vector > _compiled {}; + std::string dump(std::vector> &) const; + + private: + std::vector _sources{}; + bool _debug{false}; + std::vector> _compiled{}; }; #endif diff --git a/src/Filter.cpp b/src/Filter.cpp index e6ee0f550..0de77e88d 100644 --- a/src/Filter.cpp +++ b/src/Filter.cpp @@ -27,145 +27,130 @@ #include // cmake.h include header must come first -#include -#include #include -#include #include #include +#include +#include #include #include #include +#include + //////////////////////////////////////////////////////////////////////////////// // Take an input set of tasks and filter into a subset. -void Filter::subset (const std::vector & input, std::vector & output) -{ +void Filter::subset(const std::vector& input, std::vector& output) { Timer timer; - _startCount = (int) input.size (); + _startCount = (int)input.size(); - Context::getContext ().cli2.prepareFilter (); + Context::getContext().cli2.prepareFilter(); - std::vector > precompiled; - for (auto& a : Context::getContext ().cli2._args) - if (a.hasTag ("FILTER")) - precompiled.emplace_back (a.getToken (), a._lextype); + std::vector> precompiled; + for (auto& a : Context::getContext().cli2._args) + if (a.hasTag("FILTER")) precompiled.emplace_back(a.getToken(), a._lextype); - if (precompiled.size ()) - { + if (precompiled.size()) { Eval eval; - eval.addSource (domSource); + eval.addSource(domSource); // Debug output from Eval during compilation is useful. During evaluation // it is mostly noise. - eval.debug (Context::getContext ().config.getInteger ("debug.parser") >= 3 ? true : false); - eval.compileExpression (precompiled); + eval.debug(Context::getContext().config.getInteger("debug.parser") >= 3 ? true : false); + eval.compileExpression(precompiled); - for (auto& task : input) - { + for (auto& task : input) { // Set up context for any DOM references. - auto currentTask = Context::getContext ().withCurrentTask(&task); + auto currentTask = Context::getContext().withCurrentTask(&task); Variant var; - eval.evaluateCompiledExpression (var); - if (var.get_bool ()) - output.push_back (task); + eval.evaluateCompiledExpression(var); + if (var.get_bool()) output.push_back(task); } - eval.debug (false); - } - else + eval.debug(false); + } else output = input; - _endCount = (int) output.size (); - Context::getContext ().debug (format ("Filtered {1} tasks --> {2} tasks [list subset]", _startCount, _endCount)); - Context::getContext ().time_filter_us += timer.total_us (); + _endCount = (int)output.size(); + Context::getContext().debug( + format("Filtered {1} tasks --> {2} tasks [list subset]", _startCount, _endCount)); + Context::getContext().time_filter_us += timer.total_us(); } //////////////////////////////////////////////////////////////////////////////// // Take the set of all tasks and filter into a subset. -void Filter::subset (std::vector & output) -{ +void Filter::subset(std::vector& output) { Timer timer; - Context::getContext ().cli2.prepareFilter (); + Context::getContext().cli2.prepareFilter(); - std::vector > precompiled; - for (auto& a : Context::getContext ().cli2._args) - if (a.hasTag ("FILTER")) - precompiled.emplace_back (a.getToken (), a._lextype); + std::vector> precompiled; + for (auto& a : Context::getContext().cli2._args) + if (a.hasTag("FILTER")) precompiled.emplace_back(a.getToken(), a._lextype); // Shortcut indicates that only pending.data needs to be loaded. bool shortcut = false; - if (precompiled.size ()) - { + if (precompiled.size()) { Timer timer_pending; - auto pending = Context::getContext ().tdb2.pending_tasks (); - Context::getContext ().time_filter_us -= timer_pending.total_us (); - _startCount = (int) pending.size (); + auto pending = Context::getContext().tdb2.pending_tasks(); + Context::getContext().time_filter_us -= timer_pending.total_us(); + _startCount = (int)pending.size(); Eval eval; - eval.addSource (domSource); + eval.addSource(domSource); // Debug output from Eval during compilation is useful. During evaluation // it is mostly noise. - eval.debug (Context::getContext ().config.getInteger ("debug.parser") >= 3 ? true : false); - eval.compileExpression (precompiled); + eval.debug(Context::getContext().config.getInteger("debug.parser") >= 3 ? true : false); + eval.compileExpression(precompiled); - output.clear (); - for (auto& task : pending) - { + output.clear(); + for (auto& task : pending) { // Set up context for any DOM references. - auto currentTask = Context::getContext ().withCurrentTask(&task); + auto currentTask = Context::getContext().withCurrentTask(&task); Variant var; - eval.evaluateCompiledExpression (var); - if (var.get_bool ()) - output.push_back (task); + eval.evaluateCompiledExpression(var); + if (var.get_bool()) output.push_back(task); } - shortcut = pendingOnly (); - if (! shortcut) - { + shortcut = pendingOnly(); + if (!shortcut) { Timer timer_completed; - auto completed = Context::getContext ().tdb2.completed_tasks (); - Context::getContext ().time_filter_us -= timer_completed.total_us (); - _startCount += (int) completed.size (); + auto completed = Context::getContext().tdb2.completed_tasks(); + Context::getContext().time_filter_us -= timer_completed.total_us(); + _startCount += (int)completed.size(); - for (auto& task : completed) - { + for (auto& task : completed) { // Set up context for any DOM references. - auto currentTask = Context::getContext ().withCurrentTask(&task); + auto currentTask = Context::getContext().withCurrentTask(&task); Variant var; - eval.evaluateCompiledExpression (var); - if (var.get_bool ()) - output.push_back (task); + eval.evaluateCompiledExpression(var); + if (var.get_bool()) output.push_back(task); } } - eval.debug (false); - } - else - { - safety (); + eval.debug(false); + } else { + safety(); Timer pending_completed; - output = Context::getContext ().tdb2.all_tasks (); - Context::getContext ().time_filter_us -= pending_completed.total_us (); + output = Context::getContext().tdb2.all_tasks(); + Context::getContext().time_filter_us -= pending_completed.total_us(); } - _endCount = (int) output.size (); - Context::getContext ().debug (format ("Filtered {1} tasks --> {2} tasks [{3}]", _startCount, _endCount, (shortcut ? "pending only" : "all tasks"))); - Context::getContext ().time_filter_us += timer.total_us (); + _endCount = (int)output.size(); + Context::getContext().debug(format("Filtered {1} tasks --> {2} tasks [{3}]", _startCount, + _endCount, (shortcut ? "pending only" : "all tasks"))); + Context::getContext().time_filter_us += timer.total_us(); } //////////////////////////////////////////////////////////////////////////////// -bool Filter::hasFilter () const -{ - for (const auto& a : Context::getContext ().cli2._args) - if (a.hasTag ("FILTER")) - return true; +bool Filter::hasFilter() const { + for (const auto& a : Context::getContext().cli2._args) + if (a.hasTag("FILTER")) return true; return false; } @@ -174,11 +159,9 @@ bool Filter::hasFilter () const // If the filter contains no 'or', 'xor' or 'not' operators, and only includes // status values 'pending', 'waiting' or 'recurring', then the filter is // guaranteed to only need data from pending.data. -bool Filter::pendingOnly () const -{ +bool Filter::pendingOnly() const { // When GC is off, there are no shortcuts. - if (! Context::getContext ().config.getBoolean ("gc")) - return false; + if (!Context::getContext().config.getBoolean("gc")) return false; // To skip loading completed.data, there should be: // - 'status' in filter @@ -186,61 +169,51 @@ bool Filter::pendingOnly () const // - no 'deleted' // - no 'xor' // - no 'or' - int countStatus = 0; - int countPending = 0; - int countWaiting = 0; + int countStatus = 0; + int countPending = 0; + int countWaiting = 0; int countRecurring = 0; - int countId = (int) Context::getContext ().cli2._id_ranges.size (); - int countUUID = (int) Context::getContext ().cli2._uuid_list.size (); - int countOr = 0; - int countXor = 0; - int countNot = 0; + int countId = (int)Context::getContext().cli2._id_ranges.size(); + int countUUID = (int)Context::getContext().cli2._uuid_list.size(); + int countOr = 0; + int countXor = 0; + int countNot = 0; bool pendingTag = false; - bool activeTag = false; + bool activeTag = false; - for (const auto& a : Context::getContext ().cli2._args) - { - if (a.hasTag ("FILTER")) - { - std::string raw = a.attribute ("raw"); - std::string canonical = a.attribute ("canonical"); + for (const auto& a : Context::getContext().cli2._args) { + if (a.hasTag("FILTER")) { + std::string raw = a.attribute("raw"); + std::string canonical = a.attribute("canonical"); - if (a._lextype == Lexer::Type::op && raw == "or") ++countOr; - if (a._lextype == Lexer::Type::op && raw == "xor") ++countXor; - if (a._lextype == Lexer::Type::op && raw == "not") ++countNot; + if (a._lextype == Lexer::Type::op && raw == "or") ++countOr; + if (a._lextype == Lexer::Type::op && raw == "xor") ++countXor; + if (a._lextype == Lexer::Type::op && raw == "not") ++countNot; if (a._lextype == Lexer::Type::dom && canonical == "status") ++countStatus; - if ( raw == "pending") ++countPending; - if ( raw == "waiting") ++countWaiting; - if ( raw == "recurring") ++countRecurring; + if (raw == "pending") ++countPending; + if (raw == "waiting") ++countWaiting; + if (raw == "recurring") ++countRecurring; } } - for (const auto& word : Context::getContext ().cli2._original_args) - { - if (word.attribute ("raw") == "+PENDING") pendingTag = true; - if (word.attribute ("raw") == "+ACTIVE") activeTag = true; + for (const auto& word : Context::getContext().cli2._original_args) { + if (word.attribute("raw") == "+PENDING") pendingTag = true; + if (word.attribute("raw") == "+ACTIVE") activeTag = true; } + if (countUUID) return false; - if (countUUID) - return false; + if (countOr || countXor || countNot) return false; - if (countOr || countXor || countNot) - return false; + if (pendingTag || activeTag) return true; - if (pendingTag || activeTag) - return true; - - if (countStatus) - { - if (!countPending && !countWaiting && !countRecurring) - return false; + if (countStatus) { + if (!countPending && !countWaiting && !countRecurring) return false; return true; } - if (countId) - return true; + if (countId) return true; return false; } @@ -248,43 +221,35 @@ bool Filter::pendingOnly () const //////////////////////////////////////////////////////////////////////////////// // Disaster avoidance mechanism. If a !READONLY has no filter, then it can cause // all tasks to be modified. This is usually not intended. -void Filter::safety () const -{ - if (_safety) - { +void Filter::safety() const { + if (_safety) { bool readonly = true; bool filter = false; - for (const auto& a : Context::getContext ().cli2._args) - { - if (a.hasTag ("CMD") && - ! a.hasTag ("READONLY")) - readonly = false; + for (const auto& a : Context::getContext().cli2._args) { + if (a.hasTag("CMD") && !a.hasTag("READONLY")) readonly = false; - if (a.hasTag ("FILTER")) - filter = true; + if (a.hasTag("FILTER")) filter = true; } - if (! readonly && - ! filter) - { - if (! Context::getContext ().config.getBoolean ("allow.empty.filter")) - throw std::string ("You did not specify a filter, and with the 'allow.empty.filter' value, no action is taken."); + if (!readonly && !filter) { + if (!Context::getContext().config.getBoolean("allow.empty.filter")) + throw std::string( + "You did not specify a filter, and with the 'allow.empty.filter' value, no action is " + "taken."); // If user is willing to be asked, this can be avoided. - if (Context::getContext ().config.getBoolean ("confirmation") && - confirm ("This command has no filter, and will modify all (including completed and deleted) tasks. Are you sure?")) + if (Context::getContext().config.getBoolean("confirmation") && + confirm("This command has no filter, and will modify all (including completed and " + "deleted) tasks. Are you sure?")) return; // Sound the alarm. - throw std::string ("Command prevented from running."); + throw std::string("Command prevented from running."); } } } //////////////////////////////////////////////////////////////////////////////// -void Filter::disableSafety () -{ - _safety = false; -} +void Filter::disableSafety() { _safety = false; } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/Filter.h b/src/Filter.h index da15c68b3..2c47da6c4 100644 --- a/src/Filter.h +++ b/src/Filter.h @@ -27,28 +27,27 @@ #ifndef INCLUDED_FILTER #define INCLUDED_FILTER -#include -#include #include #include -class Filter -{ -public: - Filter () = default; +#include +#include - void subset (const std::vector &, std::vector &); - void subset (std::vector &); - bool hasFilter () const; - bool pendingOnly () const; - void safety () const; - void disableSafety (); +class Filter { + public: + Filter() = default; -private: - int _startCount {0}; - int _endCount {0}; - bool _safety {true}; + void subset(const std::vector&, std::vector&); + void subset(std::vector&); + bool hasFilter() const; + bool pendingOnly() const; + void safety() const; + void disableSafety(); + + private: + int _startCount{0}; + int _endCount{0}; + bool _safety{true}; }; #endif - diff --git a/src/Hooks.cpp b/src/Hooks.cpp index c0fdc056d..a8ad76b82 100644 --- a/src/Hooks.cpp +++ b/src/Hooks.cpp @@ -28,90 +28,83 @@ // cmake.h include header must come first #include + #include // If is included, put it after , because it includes // , and therefore would ignore the _WITH_GETLINE. #ifdef FREEBSD #define _WITH_GETLINE #endif -#include -#include -#include -#include #include -#include #include -#include -#include -#include #include +#include +#include +#include +#include #include #include +#include +#include +#include +#include #include -#define STRING_HOOK_ERROR_OBJECT "Hook Error: JSON Object '{...}' expected from hook script: {1}" -#define STRING_HOOK_ERROR_NODESC "Hook Error: JSON Object missing 'description' attribute from hook script: {1}" -#define STRING_HOOK_ERROR_NOUUID "Hook Error: JSON Object missing 'uuid' attribute from hook script: {1}" -#define STRING_HOOK_ERROR_SYNTAX "Hook Error: JSON syntax error in: {1}" -#define STRING_HOOK_ERROR_JSON "Hook Error: JSON " -#define STRING_HOOK_ERROR_NOPARSE "Hook Error: JSON failed to parse: " -#define STRING_HOOK_ERROR_BAD_NUM "Hook Error: Expected {1} JSON task(s), found {2}, in hook script: {3}" -#define STRING_HOOK_ERROR_SAME1 "Hook Error: JSON must be for the same task: {1}, in hook script: {2}" -#define STRING_HOOK_ERROR_SAME2 "Hook Error: JSON must be for the same task: {1} != {2}, in hook script: {3}" +#define STRING_HOOK_ERROR_OBJECT "Hook Error: JSON Object '{...}' expected from hook script: {1}" +#define STRING_HOOK_ERROR_NODESC \ + "Hook Error: JSON Object missing 'description' attribute from hook script: {1}" +#define STRING_HOOK_ERROR_NOUUID \ + "Hook Error: JSON Object missing 'uuid' attribute from hook script: {1}" +#define STRING_HOOK_ERROR_SYNTAX "Hook Error: JSON syntax error in: {1}" +#define STRING_HOOK_ERROR_JSON "Hook Error: JSON " +#define STRING_HOOK_ERROR_NOPARSE "Hook Error: JSON failed to parse: " +#define STRING_HOOK_ERROR_BAD_NUM \ + "Hook Error: Expected {1} JSON task(s), found {2}, in hook script: {3}" +#define STRING_HOOK_ERROR_SAME1 \ + "Hook Error: JSON must be for the same task: {1}, in hook script: {2}" +#define STRING_HOOK_ERROR_SAME2 \ + "Hook Error: JSON must be for the same task: {1} != {2}, in hook script: {3}" #define STRING_HOOK_ERROR_NOFEEDBACK "Hook Error: Expected feedback from failing hook script: {1}" //////////////////////////////////////////////////////////////////////////////// -void Hooks::initialize () -{ - _debug = Context::getContext ().config.getInteger ("debug.hooks"); +void Hooks::initialize() { + _debug = Context::getContext().config.getInteger("debug.hooks"); // Scan // /hooks Directory d; - if (Context::getContext ().config.has ("hooks.location")) - { - d = Directory (Context::getContext ().config.get ("hooks.location")); - } - else - { - d = Directory (Context::getContext ().config.get ("data.location")); + if (Context::getContext().config.has("hooks.location")) { + d = Directory(Context::getContext().config.get("hooks.location")); + } else { + d = Directory(Context::getContext().config.get("data.location")); d += "hooks"; } - if (d.is_directory () && - d.readable ()) - { - _scripts = d.list (); - std::sort (_scripts.begin (), _scripts.end ()); + if (d.is_directory() && d.readable()) { + _scripts = d.list(); + std::sort(_scripts.begin(), _scripts.end()); - if (_debug >= 1) - { - for (auto& i : _scripts) - { - Path p (i); - if (! p.is_directory ()) - { - std::string name = p.name (); - if (name.substr (0, 6) == "on-add" || - name.substr (0, 9) == "on-modify" || - name.substr (0, 9) == "on-launch" || - name.substr (0, 7) == "on-exit") - Context::getContext ().debug ("Found hook script " + i); + if (_debug >= 1) { + for (auto& i : _scripts) { + Path p(i); + if (!p.is_directory()) { + std::string name = p.name(); + if (name.substr(0, 6) == "on-add" || name.substr(0, 9) == "on-modify" || + name.substr(0, 9) == "on-launch" || name.substr(0, 7) == "on-exit") + Context::getContext().debug("Found hook script " + i); else - Context::getContext ().debug ("Found misnamed hook script " + i); + Context::getContext().debug("Found misnamed hook script " + i); } } } - } - else if (_debug >= 1) - Context::getContext ().debug ("Hook directory not readable: " + d._data); + } else if (_debug >= 1) + Context::getContext().debug("Hook directory not readable: " + d._data); - _enabled = Context::getContext ().config.getBoolean ("hooks"); + _enabled = Context::getContext().config.getBoolean("hooks"); } //////////////////////////////////////////////////////////////////////////////// -bool Hooks::enable (bool value) -{ +bool Hooks::enable(bool value) { bool old_value = _enabled; _enabled = value; return old_value; @@ -129,45 +122,36 @@ bool Hooks::enable (bool value) // - all emitted non-JSON lines are considered feedback or error messages // depending on the status code. // -void Hooks::onLaunch () const -{ - if (! _enabled) - return; +void Hooks::onLaunch() const { + if (!_enabled) return; Timer timer; - std::vector matchingScripts = scripts ("on-launch"); - if (matchingScripts.size ()) - { - for (auto& script : matchingScripts) - { - std::vector input; - std::vector output; - int status = callHookScript (script, input, output); + std::vector matchingScripts = scripts("on-launch"); + if (matchingScripts.size()) { + for (auto& script : matchingScripts) { + std::vector input; + std::vector output; + int status = callHookScript(script, input, output); - std::vector outputJSON; - std::vector outputFeedback; - separateOutput (output, outputJSON, outputFeedback); + std::vector outputJSON; + std::vector outputFeedback; + separateOutput(output, outputJSON, outputFeedback); - assertNTasks (outputJSON, 0, script); + assertNTasks(outputJSON, 0, script); - if (status == 0) - { - for (auto& message : outputFeedback) - Context::getContext ().footnote (message); - } - else - { - assertFeedback (outputFeedback, script); - for (auto& message : outputFeedback) - Context::getContext ().error (message); + if (status == 0) { + for (auto& message : outputFeedback) Context::getContext().footnote(message); + } else { + assertFeedback(outputFeedback, script); + for (auto& message : outputFeedback) Context::getContext().error(message); throw 0; // This is how hooks silently terminate processing. } } } - Context::getContext ().time_hooks_us += timer.total_us (); + Context::getContext().time_hooks_us += timer.total_us(); } //////////////////////////////////////////////////////////////////////////////// @@ -182,55 +166,45 @@ void Hooks::onLaunch () const // - all emitted non-JSON lines are considered feedback or error messages // depending on the status code. // -void Hooks::onExit () const -{ - if (! _enabled) - return; +void Hooks::onExit() const { + if (!_enabled) return; Timer timer; - std::vector matchingScripts = scripts ("on-exit"); - if (matchingScripts.size ()) - { + std::vector matchingScripts = scripts("on-exit"); + if (matchingScripts.size()) { // Get the set of changed tasks. - std::vector tasks; - Context::getContext ().tdb2.get_changes (tasks); + std::vector tasks; + Context::getContext().tdb2.get_changes(tasks); // Convert to a vector of strings. - std::vector input; + std::vector input; input.reserve(tasks.size()); - for (auto& t : tasks) - input.push_back (t.composeJSON ()); + for (auto& t : tasks) input.push_back(t.composeJSON()); // Call the hook scripts, with the invariant input. - for (auto& script : matchingScripts) - { - std::vector output; - int status = callHookScript (script, input, output); + for (auto& script : matchingScripts) { + std::vector output; + int status = callHookScript(script, input, output); - std::vector outputJSON; - std::vector outputFeedback; - separateOutput (output, outputJSON, outputFeedback); + std::vector outputJSON; + std::vector outputFeedback; + separateOutput(output, outputJSON, outputFeedback); - assertNTasks (outputJSON, 0, script); + assertNTasks(outputJSON, 0, script); - if (status == 0) - { - for (auto& message : outputFeedback) - Context::getContext ().footnote (message); - } - else - { - assertFeedback (outputFeedback, script); - for (auto& message : outputFeedback) - Context::getContext ().error (message); + if (status == 0) { + for (auto& message : outputFeedback) Context::getContext().footnote(message); + } else { + assertFeedback(outputFeedback, script); + for (auto& message : outputFeedback) Context::getContext().error(message); throw 0; // This is how hooks silently terminate processing. } } } - Context::getContext ().time_hooks_us += timer.total_us (); + Context::getContext().time_hooks_us += timer.total_us(); } //////////////////////////////////////////////////////////////////////////////// @@ -245,57 +219,48 @@ void Hooks::onExit () const // - all emitted non-JSON lines are considered feedback or error messages // depending on the status code. // -void Hooks::onAdd (Task& task) const -{ - if (! _enabled) - return; +void Hooks::onAdd(Task& task) const { + if (!_enabled) return; Timer timer; - std::vector matchingScripts = scripts ("on-add"); - if (matchingScripts.size ()) - { + std::vector matchingScripts = scripts("on-add"); + if (matchingScripts.size()) { // Convert task to a vector of strings. - std::vector input; - input.push_back (task.composeJSON ()); + std::vector input; + input.push_back(task.composeJSON()); // Call the hook scripts. - for (auto& script : matchingScripts) - { - std::vector output; - int status = callHookScript (script, input, output); + for (auto& script : matchingScripts) { + std::vector output; + int status = callHookScript(script, input, output); - std::vector outputJSON; - std::vector outputFeedback; - separateOutput (output, outputJSON, outputFeedback); + std::vector outputJSON; + std::vector outputFeedback; + separateOutput(output, outputJSON, outputFeedback); - if (status == 0) - { - assertNTasks (outputJSON, 1, script); - assertValidJSON (outputJSON, script); - assertSameTask (outputJSON, task, script); + if (status == 0) { + assertNTasks(outputJSON, 1, script); + assertValidJSON(outputJSON, script); + assertSameTask(outputJSON, task, script); // Propagate forward to the next script. input[0] = outputJSON[0]; - for (auto& message : outputFeedback) - Context::getContext ().footnote (message); - } - else - { - assertFeedback (outputFeedback, script); - for (auto& message : outputFeedback) - Context::getContext ().error (message); + for (auto& message : outputFeedback) Context::getContext().footnote(message); + } else { + assertFeedback(outputFeedback, script); + for (auto& message : outputFeedback) Context::getContext().error(message); throw 0; // This is how hooks silently terminate processing. } } // Transfer the modified task back to the original task. - task = Task (input[0]); + task = Task(input[0]); } - Context::getContext ().time_hooks_us += timer.total_us (); + Context::getContext().time_hooks_us += timer.total_us(); } //////////////////////////////////////////////////////////////////////////////// @@ -311,76 +276,60 @@ void Hooks::onAdd (Task& task) const // - all emitted non-JSON lines are considered feedback or error messages // depending on the status code. // -void Hooks::onModify (const Task& before, Task& after) const -{ - if (! _enabled) - return; +void Hooks::onModify(const Task& before, Task& after) const { + if (!_enabled) return; Timer timer; - std::vector matchingScripts = scripts ("on-modify"); - if (matchingScripts.size ()) - { + std::vector matchingScripts = scripts("on-modify"); + if (matchingScripts.size()) { // Convert vector of tasks to a vector of strings. - std::vector input; - input.push_back (before.composeJSON ()); // [line 0] original, never changes - input.push_back (after.composeJSON ()); // [line 1] modified + std::vector input; + input.push_back(before.composeJSON()); // [line 0] original, never changes + input.push_back(after.composeJSON()); // [line 1] modified // Call the hook scripts. - for (auto& script : matchingScripts) - { - std::vector output; - int status = callHookScript (script, input, output); + for (auto& script : matchingScripts) { + std::vector output; + int status = callHookScript(script, input, output); - std::vector outputJSON; - std::vector outputFeedback; - separateOutput (output, outputJSON, outputFeedback); + std::vector outputJSON; + std::vector outputFeedback; + separateOutput(output, outputJSON, outputFeedback); - if (status == 0) - { - assertNTasks (outputJSON, 1, script); - assertValidJSON (outputJSON, script); - assertSameTask (outputJSON, before, script); + if (status == 0) { + assertNTasks(outputJSON, 1, script); + assertValidJSON(outputJSON, script); + assertSameTask(outputJSON, before, script); // Propagate accepted changes forward to the next script. input[1] = outputJSON[0]; - for (auto& message : outputFeedback) - Context::getContext ().footnote (message); - } - else - { - assertFeedback (outputFeedback, script); - for (auto& message : outputFeedback) - Context::getContext ().error (message); + for (auto& message : outputFeedback) Context::getContext().footnote(message); + } else { + assertFeedback(outputFeedback, script); + for (auto& message : outputFeedback) Context::getContext().error(message); throw 0; // This is how hooks silently terminate processing. } } - after = Task (input[1]); + after = Task(input[1]); } - Context::getContext ().time_hooks_us += timer.total_us (); + Context::getContext().time_hooks_us += timer.total_us(); } //////////////////////////////////////////////////////////////////////////////// -std::vector Hooks::list () const -{ - return _scripts; -} +std::vector Hooks::list() const { return _scripts; } //////////////////////////////////////////////////////////////////////////////// -std::vector Hooks::scripts (const std::string& event) const -{ - std::vector matching; - for (const auto& i : _scripts) - { - if (i.find ("/" + event) != std::string::npos) - { - File script (i); - if (script.executable ()) - matching.push_back (i); +std::vector Hooks::scripts(const std::string& event) const { + std::vector matching; + for (const auto& i : _scripts) { + if (i.find("/" + event) != std::string::npos) { + File script(i); + if (script.executable()) matching.push_back(i); } } @@ -388,124 +337,95 @@ std::vector Hooks::scripts (const std::string& event) const } //////////////////////////////////////////////////////////////////////////////// -void Hooks::separateOutput ( - const std::vector & output, - std::vector & json, - std::vector & feedback) const -{ - for (auto& i : output) - { - if (isJSON (i)) - json.push_back (i); +void Hooks::separateOutput(const std::vector& output, std::vector& json, + std::vector& feedback) const { + for (auto& i : output) { + if (isJSON(i)) + json.push_back(i); else - feedback.push_back (i); + feedback.push_back(i); } } //////////////////////////////////////////////////////////////////////////////// -bool Hooks::isJSON (const std::string& input) const -{ - return input.length () > 2 && - input[0] == '{' && - input[input.length () - 1] == '}'; +bool Hooks::isJSON(const std::string& input) const { + return input.length() > 2 && input[0] == '{' && input[input.length() - 1] == '}'; } //////////////////////////////////////////////////////////////////////////////// -void Hooks::assertValidJSON ( - const std::vector & input, - const std::string& script) const -{ - for (auto& i : input) - { - if (i.length () < 3 || - i[0] != '{' || - i[i.length () - 1] != '}') - { - Context::getContext ().error (format (STRING_HOOK_ERROR_OBJECT, Path (script).name ())); +void Hooks::assertValidJSON(const std::vector& input, + const std::string& script) const { + for (auto& i : input) { + if (i.length() < 3 || i[0] != '{' || i[i.length() - 1] != '}') { + Context::getContext().error(format(STRING_HOOK_ERROR_OBJECT, Path(script).name())); throw 0; } - try - { - json::value* root = json::parse (i); - if (root->type () != json::j_object) - { - Context::getContext ().error (format (STRING_HOOK_ERROR_OBJECT, Path (script).name ())); + try { + json::value* root = json::parse(i); + if (root->type() != json::j_object) { + Context::getContext().error(format(STRING_HOOK_ERROR_OBJECT, Path(script).name())); throw 0; } - if (((json::object*)root)->_data.find ("description") == ((json::object*)root)->_data.end ()) - { - Context::getContext ().error (format (STRING_HOOK_ERROR_NODESC, Path (script).name ())); + if (((json::object*)root)->_data.find("description") == ((json::object*)root)->_data.end()) { + Context::getContext().error(format(STRING_HOOK_ERROR_NODESC, Path(script).name())); throw 0; } - if (((json::object*)root)->_data.find ("uuid") == ((json::object*)root)->_data.end ()) - { - Context::getContext ().error (format (STRING_HOOK_ERROR_NOUUID, Path (script).name ())); + if (((json::object*)root)->_data.find("uuid") == ((json::object*)root)->_data.end()) { + Context::getContext().error(format(STRING_HOOK_ERROR_NOUUID, Path(script).name())); throw 0; } delete root; } - catch (const std::string& e) - { - Context::getContext ().error (format (STRING_HOOK_ERROR_SYNTAX, i)); - if (_debug) - Context::getContext ().error (STRING_HOOK_ERROR_JSON + e); + catch (const std::string& e) { + Context::getContext().error(format(STRING_HOOK_ERROR_SYNTAX, i)); + if (_debug) Context::getContext().error(STRING_HOOK_ERROR_JSON + e); throw 0; } - catch (...) - { - Context::getContext ().error (STRING_HOOK_ERROR_NOPARSE + i); + catch (...) { + Context::getContext().error(STRING_HOOK_ERROR_NOPARSE + i); throw 0; } } } //////////////////////////////////////////////////////////////////////////////// -void Hooks::assertNTasks ( - const std::vector & input, - unsigned int n, - const std::string& script) const -{ - if (input.size () != n) - { - Context::getContext ().error (format (STRING_HOOK_ERROR_BAD_NUM, n, (int) input.size (), Path (script).name ())); +void Hooks::assertNTasks(const std::vector& input, unsigned int n, + const std::string& script) const { + if (input.size() != n) { + Context::getContext().error( + format(STRING_HOOK_ERROR_BAD_NUM, n, (int)input.size(), Path(script).name())); throw 0; } } //////////////////////////////////////////////////////////////////////////////// -void Hooks::assertSameTask ( - const std::vector & input, - const Task& task, - const std::string& script) const -{ - std::string uuid = task.get ("uuid"); +void Hooks::assertSameTask(const std::vector& input, const Task& task, + const std::string& script) const { + std::string uuid = task.get("uuid"); - for (auto& i : input) - { - auto root_obj = (json::object*)json::parse (i); + for (auto& i : input) { + auto root_obj = (json::object*)json::parse(i); // If there is no UUID at all. - auto u = root_obj->_data.find ("uuid"); - if (u == root_obj->_data.end () || - u->second->type () != json::j_string) - { - Context::getContext ().error (format (STRING_HOOK_ERROR_SAME1, uuid, Path (script).name ())); + auto u = root_obj->_data.find("uuid"); + if (u == root_obj->_data.end() || u->second->type() != json::j_string) { + Context::getContext().error(format(STRING_HOOK_ERROR_SAME1, uuid, Path(script).name())); throw 0; } - auto up = (json::string*) u->second; - auto text = up->dump (); - Lexer::dequote (text); - std::string json_uuid = json::decode (text); - if (json_uuid != uuid) - { - Context::getContext ().error (format (STRING_HOOK_ERROR_SAME2, uuid, json_uuid, Path (script).name ())); + auto up = (json::string*)u->second; + auto text = up->dump(); + Lexer::dequote(text); + std::string json_uuid = json::decode(text); + if (json_uuid != uuid) { + Context::getContext().error( + format(STRING_HOOK_ERROR_SAME2, uuid, json_uuid, Path(script).name())); throw 0; } @@ -514,101 +434,82 @@ void Hooks::assertSameTask ( } //////////////////////////////////////////////////////////////////////////////// -void Hooks::assertFeedback ( - const std::vector & input, - const std::string& script) const -{ +void Hooks::assertFeedback(const std::vector& input, const std::string& script) const { bool foundSomething = false; for (auto& i : input) - if (nontrivial (i)) - foundSomething = true; + if (nontrivial(i)) foundSomething = true; - if (! foundSomething) - { - Context::getContext ().error (format (STRING_HOOK_ERROR_NOFEEDBACK, Path (script).name ())); + if (!foundSomething) { + Context::getContext().error(format(STRING_HOOK_ERROR_NOFEEDBACK, Path(script).name())); throw 0; } } //////////////////////////////////////////////////////////////////////////////// -std::vector & Hooks::buildHookScriptArgs (std::vector & args) const -{ +std::vector& Hooks::buildHookScriptArgs(std::vector& args) const { Variant v; // Hooks API version. - args.push_back ("api:2"); + args.push_back("api:2"); // Command line Taskwarrior was called with. - getDOM ("context.args", v); - args.push_back ("args:" + std::string (v)); + getDOM("context.args", v); + args.push_back("args:" + std::string(v)); // Command to be executed. - args.push_back ("command:" + Context::getContext ().cli2.getCommand ()); + args.push_back("command:" + Context::getContext().cli2.getCommand()); // rc file used after applying all overrides. - args.push_back ("rc:" + Context::getContext ().rc_file._data); + args.push_back("rc:" + Context::getContext().rc_file._data); // Directory containing *.data files. - args.push_back ("data:" + Context::getContext ().data_dir._data); + args.push_back("data:" + Context::getContext().data_dir._data); // Taskwarrior version, same as returned by "task --version" - args.push_back ("version:" + std::string(VERSION)); + args.push_back("version:" + std::string(VERSION)); return args; } //////////////////////////////////////////////////////////////////////////////// -int Hooks::callHookScript ( - const std::string& script, - const std::vector & input, - std::vector & output) const -{ - if (_debug >= 1) - Context::getContext ().debug ("Hook: Calling " + script); +int Hooks::callHookScript(const std::string& script, const std::vector& input, + std::vector& output) const { + if (_debug >= 1) Context::getContext().debug("Hook: Calling " + script); - if (_debug >= 2) - { - Context::getContext ().debug ("Hook: input"); - for (const auto& i : input) - Context::getContext ().debug (" " + i); + if (_debug >= 2) { + Context::getContext().debug("Hook: input"); + for (const auto& i : input) Context::getContext().debug(" " + i); } std::string inputStr; - for (const auto& i : input) - inputStr += i + "\n"; + for (const auto& i : input) inputStr += i + "\n"; - std::vector args; - buildHookScriptArgs (args); - if (_debug >= 2) - { - Context::getContext ().debug ("Hooks: args"); - for (const auto& arg: args) - Context::getContext ().debug (" " + arg); + std::vector args; + buildHookScriptArgs(args); + if (_debug >= 2) { + Context::getContext().debug("Hooks: args"); + for (const auto& arg : args) Context::getContext().debug(" " + arg); } // Measure time for each hook if running in debug int status; std::string outputStr; - if (_debug >= 2) - { + if (_debug >= 2) { Timer timer; - status = execute (script, args, inputStr, outputStr); - Context::getContext ().debugTiming (format ("Hooks::execute ({1})", script), timer); - } - else - status = execute (script, args, inputStr, outputStr); + status = execute(script, args, inputStr, outputStr); + Context::getContext().debugTiming(format("Hooks::execute ({1})", script), timer); + } else + status = execute(script, args, inputStr, outputStr); - output = split (outputStr, '\n'); + output = split(outputStr, '\n'); - if (_debug >= 2) - { - Context::getContext ().debug ("Hook: output"); + if (_debug >= 2) { + Context::getContext().debug("Hook: output"); for (const auto& i : output) - if (i != "") - Context::getContext ().debug (" " + i); + if (i != "") Context::getContext().debug(" " + i); - Context::getContext ().debug (format ("Hook: Completed with status {1}", status)); - Context::getContext ().debug (" "); // Blank line + Context::getContext().debug(format("Hook: Completed with status {1}", status)); + Context::getContext().debug(" "); // Blank line } return status; diff --git a/src/Hooks.h b/src/Hooks.h index a65bc9ff3..6496674b7 100644 --- a/src/Hooks.h +++ b/src/Hooks.h @@ -27,37 +27,39 @@ #ifndef INCLUDED_HOOKS #define INCLUDED_HOOKS -#include -#include #include -class Hooks -{ -public: - Hooks () = default; - void initialize (); - bool enable (bool); - void onLaunch () const; - void onExit () const; - void onAdd (Task&) const; - void onModify (const Task&, Task&) const; - std::vector list () const; +#include +#include -private: - std::vector scripts (const std::string&) const; - void separateOutput (const std::vector &, std::vector &, std::vector &) const; - bool isJSON (const std::string&) const; - void assertValidJSON (const std::vector &, const std::string&) const; - void assertNTasks (const std::vector &, unsigned int, const std::string&) const; - void assertSameTask (const std::vector &, const Task&, const std::string&) const; - void assertFeedback (const std::vector &, const std::string&) const; - std::vector & buildHookScriptArgs (std::vector &) const; - int callHookScript (const std::string&, const std::vector &, std::vector &) const; +class Hooks { + public: + Hooks() = default; + void initialize(); + bool enable(bool); + void onLaunch() const; + void onExit() const; + void onAdd(Task&) const; + void onModify(const Task&, Task&) const; + std::vector list() const; -private: - bool _enabled {true}; - int _debug {0}; - std::vector _scripts {}; + private: + std::vector scripts(const std::string&) const; + void separateOutput(const std::vector&, std::vector&, + std::vector&) const; + bool isJSON(const std::string&) const; + void assertValidJSON(const std::vector&, const std::string&) const; + void assertNTasks(const std::vector&, unsigned int, const std::string&) const; + void assertSameTask(const std::vector&, const Task&, const std::string&) const; + void assertFeedback(const std::vector&, const std::string&) const; + std::vector& buildHookScriptArgs(std::vector&) const; + int callHookScript(const std::string&, const std::vector&, + std::vector&) const; + + private: + bool _enabled{true}; + int _debug{0}; + std::vector _scripts{}; }; #endif diff --git a/src/Lexer.cpp b/src/Lexer.cpp index d11a8f335..0c3b8a38e 100644 --- a/src/Lexer.cpp +++ b/src/Lexer.cpp @@ -27,42 +27,34 @@ #include // cmake.h include header must come first -#include -#include -#include #include #include +#include +#include #include #include +#include + static const std::string uuid_pattern = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"; static const unsigned int uuid_min_length = 8; std::string Lexer::dateFormat = ""; std::string::size_type Lexer::minimumMatchLength = 3; -std::map Lexer::attributes; - +std::map Lexer::attributes; //////////////////////////////////////////////////////////////////////////////// -Lexer::Lexer (const std::string& text) -: _text (text) -, _cursor (0) -, _eos (text.size ()) -{ -} +Lexer::Lexer(const std::string& text) : _text(text), _cursor(0), _eos(text.size()) {} //////////////////////////////////////////////////////////////////////////////// // When a Lexer object is constructed with a string, this method walks through // the stream of low-level tokens. -bool Lexer::token (std::string& token, Lexer::Type& type) -{ +bool Lexer::token(std::string& token, Lexer::Type& type) { // Eat white space. - while (unicodeWhitespace (_text[_cursor])) - utf8_next_char (_text, _cursor); + while (unicodeWhitespace(_text[_cursor])) utf8_next_char(_text, _cursor); // Terminate at EOS. - if (isEOS ()) - return false; + if (isEOS()) return false; // The sequence is specific, and must follow these rules: // - date < duration < uuid < identifier @@ -74,24 +66,12 @@ bool Lexer::token (std::string& token, Lexer::Type& type) // - path < substitution < pattern // - set < number // - word last - if (isString (token, type, "'\"") || - isDate (token, type) || - isDuration (token, type) || - isURL (token, type) || - isPair (token, type) || - isUUID (token, type, true) || - isSet (token, type) || - isDOM (token, type) || - isHexNumber (token, type) || - isNumber (token, type) || - isSeparator (token, type) || - isTag (token, type) || - isPath (token, type) || - isSubstitution (token, type) || - isPattern (token, type) || - isOperator (token, type) || - isIdentifier (token, type) || - isWord (token, type)) + if (isString(token, type, "'\"") || isDate(token, type) || isDuration(token, type) || + isURL(token, type) || isPair(token, type) || isUUID(token, type, true) || + isSet(token, type) || isDOM(token, type) || isHexNumber(token, type) || + isNumber(token, type) || isSeparator(token, type) || isTag(token, type) || + isPath(token, type) || isSubstitution(token, type) || isPattern(token, type) || + isOperator(token, type) || isIdentifier(token, type) || isWord(token, type)) return true; return false; @@ -99,70 +79,78 @@ bool Lexer::token (std::string& token, Lexer::Type& type) //////////////////////////////////////////////////////////////////////////////// // This static method tokenizes the input, but discards the type information. -std::vector Lexer::split (const std::string& text) -{ - std::vector all; +std::vector Lexer::split(const std::string& text) { + std::vector all; std::string token; Lexer::Type ignored; - Lexer l (text); - while (l.token (token, ignored)) - all.push_back (token); + Lexer l(text); + while (l.token(token, ignored)) all.push_back(token); return all; } //////////////////////////////////////////////////////////////////////////////// // No L10N - these are for internal purposes. -const std::string Lexer::typeName (const Lexer::Type& type) -{ - switch (type) - { - case Lexer::Type::uuid: return "uuid"; - case Lexer::Type::number: return "number"; - case Lexer::Type::hex: return "hex"; - case Lexer::Type::string: return "string"; - case Lexer::Type::url: return "url"; - case Lexer::Type::pair: return "pair"; - case Lexer::Type::set: return "set"; - case Lexer::Type::separator: return "separator"; - case Lexer::Type::tag: return "tag"; - case Lexer::Type::path: return "path"; - case Lexer::Type::substitution: return "substitution"; - case Lexer::Type::pattern: return "pattern"; - case Lexer::Type::op: return "op"; - case Lexer::Type::dom: return "dom"; - case Lexer::Type::identifier: return "identifier"; - case Lexer::Type::word: return "word"; - case Lexer::Type::date: return "date"; - case Lexer::Type::duration: return "duration"; +const std::string Lexer::typeName(const Lexer::Type& type) { + switch (type) { + case Lexer::Type::uuid: + return "uuid"; + case Lexer::Type::number: + return "number"; + case Lexer::Type::hex: + return "hex"; + case Lexer::Type::string: + return "string"; + case Lexer::Type::url: + return "url"; + case Lexer::Type::pair: + return "pair"; + case Lexer::Type::set: + return "set"; + case Lexer::Type::separator: + return "separator"; + case Lexer::Type::tag: + return "tag"; + case Lexer::Type::path: + return "path"; + case Lexer::Type::substitution: + return "substitution"; + case Lexer::Type::pattern: + return "pattern"; + case Lexer::Type::op: + return "op"; + case Lexer::Type::dom: + return "dom"; + case Lexer::Type::identifier: + return "identifier"; + case Lexer::Type::word: + return "word"; + case Lexer::Type::date: + return "date"; + case Lexer::Type::duration: + return "duration"; } return "unknown"; } //////////////////////////////////////////////////////////////////////////////// -bool Lexer::isIdentifierStart (int c) -{ - return c && // Include null character check. - ! unicodeWhitespace (c) && - ! unicodeLatinDigit (c) && - ! isSingleCharOperator (c) && - ! isPunctuation (c); +bool Lexer::isIdentifierStart(int c) { + return c && // Include null character check. + !unicodeWhitespace(c) && !unicodeLatinDigit(c) && !isSingleCharOperator(c) && + !isPunctuation(c); } //////////////////////////////////////////////////////////////////////////////// -bool Lexer::isIdentifierNext (int c) -{ - return c && // Include null character check. - c != ':' && // Used in isPair. - c != '=' && // Used in isPair. - ! unicodeWhitespace (c) && - ! isSingleCharOperator (c); +bool Lexer::isIdentifierNext(int c) { + return c && // Include null character check. + c != ':' && // Used in isPair. + c != '=' && // Used in isPair. + !unicodeWhitespace(c) && !isSingleCharOperator(c); } //////////////////////////////////////////////////////////////////////////////// -bool Lexer::isSingleCharOperator (int c) -{ +bool Lexer::isSingleCharOperator(int c) { return c == '+' || // Addition c == '-' || // Subtraction or unary minus = ambiguous c == '*' || // Multiplication @@ -179,129 +167,95 @@ bool Lexer::isSingleCharOperator (int c) } //////////////////////////////////////////////////////////////////////////////// -bool Lexer::isDoubleCharOperator (int c0, int c1, int c2) -{ - return (c0 == '=' && c1 == '=') || - (c0 == '!' && c1 == '=') || - (c0 == '<' && c1 == '=') || - (c0 == '>' && c1 == '=') || - (c0 == 'o' && c1 == 'r' && isBoundary (c1, c2)) || - (c0 == '|' && c1 == '|') || - (c0 == '&' && c1 == '&') || - (c0 == '!' && c1 == '~'); +bool Lexer::isDoubleCharOperator(int c0, int c1, int c2) { + return (c0 == '=' && c1 == '=') || (c0 == '!' && c1 == '=') || (c0 == '<' && c1 == '=') || + (c0 == '>' && c1 == '=') || (c0 == 'o' && c1 == 'r' && isBoundary(c1, c2)) || + (c0 == '|' && c1 == '|') || (c0 == '&' && c1 == '&') || (c0 == '!' && c1 == '~'); } //////////////////////////////////////////////////////////////////////////////// -bool Lexer::isTripleCharOperator (int c0, int c1, int c2, int c3) -{ - return (c0 == 'a' && c1 == 'n' && c2 == 'd' && isBoundary (c2, c3)) || - (c0 == 'x' && c1 == 'o' && c2 == 'r' && isBoundary (c2, c3)) || +bool Lexer::isTripleCharOperator(int c0, int c1, int c2, int c3) { + return (c0 == 'a' && c1 == 'n' && c2 == 'd' && isBoundary(c2, c3)) || + (c0 == 'x' && c1 == 'o' && c2 == 'r' && isBoundary(c2, c3)) || (c0 == '!' && c1 == '=' && c2 == '='); } //////////////////////////////////////////////////////////////////////////////// -bool Lexer::isBoundary (int left, int right) -{ +bool Lexer::isBoundary(int left, int right) { // EOS - if (right == '\0') return true; + if (right == '\0') return true; // XOR - if (unicodeLatinAlpha (left) != unicodeLatinAlpha (right)) return true; - if (unicodeLatinDigit (left) != unicodeLatinDigit (right)) return true; - if (unicodeWhitespace (left) != unicodeWhitespace (right)) return true; + if (unicodeLatinAlpha(left) != unicodeLatinAlpha(right)) return true; + if (unicodeLatinDigit(left) != unicodeLatinDigit(right)) return true; + if (unicodeWhitespace(left) != unicodeWhitespace(right)) return true; // OR - if (isPunctuation (left) || isPunctuation (right)) return true; + if (isPunctuation(left) || isPunctuation(right)) return true; return false; } //////////////////////////////////////////////////////////////////////////////// -bool Lexer::isHardBoundary (int left, int right) -{ +bool Lexer::isHardBoundary(int left, int right) { // EOS - if (right == '\0') - return true; + if (right == '\0') return true; // FILTER operators that don't need to be surrounded by whitespace. - if (left == '(' || - left == ')' || - right == '(' || - right == ')') - return true; + if (left == '(' || left == ')' || right == '(' || right == ')') return true; return false; } //////////////////////////////////////////////////////////////////////////////// -bool Lexer::isPunctuation (int c) -{ - return isprint (c) && - c != ' ' && - c != '@' && - c != '#' && - c != '$' && - c != '_' && - ! unicodeLatinDigit (c) && - ! unicodeLatinAlpha (c); +bool Lexer::isPunctuation(int c) { + return isprint(c) && c != ' ' && c != '@' && c != '#' && c != '$' && c != '_' && + !unicodeLatinDigit(c) && !unicodeLatinAlpha(c); } //////////////////////////////////////////////////////////////////////////////// // Assumes that quotes is a string containing a non-trivial set of quote // characters. -void Lexer::dequote (std::string& input, const std::string& quotes) -{ +void Lexer::dequote(std::string& input, const std::string& quotes) { int quote = input[0]; - if (quotes.find (quote) != std::string::npos) - { - size_t len = input.length (); - if (quote == input[len - 1]) - input = input.substr (1, len - 2); + if (quotes.find(quote) != std::string::npos) { + size_t len = input.length(); + if (quote == input[len - 1]) input = input.substr(1, len - 2); } } //////////////////////////////////////////////////////////////////////////////// // Detects characters in an input string that indicate quotes were required, or // escapes, to get them past the shell. -bool Lexer::wasQuoted (const std::string& input) -{ - if (input.find_first_of (" \t()<>&~") != std::string::npos) - return true; +bool Lexer::wasQuoted(const std::string& input) { + if (input.find_first_of(" \t()<>&~") != std::string::npos) return true; return false; } //////////////////////////////////////////////////////////////////////////////// -bool Lexer::isEOS () const -{ - return _cursor >= _eos; -} +bool Lexer::isEOS() const { return _cursor >= _eos; } //////////////////////////////////////////////////////////////////////////////// // Converts '0' -> 0 // '9' -> 9 // 'a'/'A' -> 10 // 'f'/'F' -> 15 -int Lexer::hexToInt (int c) -{ - if (c >= '0' && c <= '9') return (c - '0'); - else if (c >= 'a' && c <= 'f') return (c - 'a' + 10); - else return (c - 'A' + 10); +int Lexer::hexToInt(int c) { + if (c >= '0' && c <= '9') + return (c - '0'); + else if (c >= 'a' && c <= 'f') + return (c - 'a' + 10); + else + return (c - 'A' + 10); } //////////////////////////////////////////////////////////////////////////////// -int Lexer::hexToInt (int c0, int c1) -{ - return (hexToInt (c0) << 4) + hexToInt (c1); -} +int Lexer::hexToInt(int c0, int c1) { return (hexToInt(c0) << 4) + hexToInt(c1); } //////////////////////////////////////////////////////////////////////////////// -int Lexer::hexToInt (int c0, int c1, int c2, int c3) -{ - return (hexToInt (c0) << 12) + - (hexToInt (c1) << 8) + - (hexToInt (c2) << 4) + - hexToInt (c3); +int Lexer::hexToInt(int c0, int c1, int c2, int c3) { + return (hexToInt(c0) << 12) + (hexToInt(c1) << 8) + (hexToInt(c2) << 4) + hexToInt(c3); } //////////////////////////////////////////////////////////////////////////////// @@ -310,16 +264,10 @@ int Lexer::hexToInt (int c0, int c1, int c2, int c3) // left: wonderful // right: wonderbread // returns: ^ 6 -std::string::size_type Lexer::commonLength ( - const std::string& left, - const std::string& right) -{ +std::string::size_type Lexer::commonLength(const std::string& left, const std::string& right) { std::string::size_type l = 0; std::string::size_type r = 0; - while (left[l] == right[r] && - utf8_next_char (left, l) && - utf8_next_char (right, r)) - ; + while (left[l] == right[r] && utf8_next_char(left, l) && utf8_next_char(right, r)); return l; } @@ -332,138 +280,106 @@ std::string::size_type Lexer::commonLength ( // right: prowonderbread // r: ^ // returns: ^ 6 -std::string::size_type Lexer::commonLength ( - const std::string& left, - std::string::size_type l, - const std::string& right, - std::string::size_type r) -{ - while (left[l] == right[r] && - utf8_next_char (left, l) && - utf8_next_char (right, r)) - ; +std::string::size_type Lexer::commonLength(const std::string& left, std::string::size_type l, + const std::string& right, std::string::size_type r) { + while (left[l] == right[r] && utf8_next_char(left, l) && utf8_next_char(right, r)); return l; } //////////////////////////////////////////////////////////////////////////////// -std::string Lexer::commify (const std::string& data) -{ +std::string Lexer::commify(const std::string& data) { // First scan for decimal point and end of digits. int decimalPoint = -1; - int end = -1; + int end = -1; int i; - for (int i = 0; i < (int) data.length (); ++i) - { - if (unicodeLatinDigit (data[i])) - end = i; + for (int i = 0; i < (int)data.length(); ++i) { + if (unicodeLatinDigit(data[i])) end = i; - if (data[i] == '.') - decimalPoint = i; + if (data[i] == '.') decimalPoint = i; } std::string result; - if (decimalPoint != -1) - { + if (decimalPoint != -1) { // In reverse order, transfer all digits up to, and including the decimal // point. - for (i = (int) data.length () - 1; i >= decimalPoint; --i) - result += data[i]; + for (i = (int)data.length() - 1; i >= decimalPoint; --i) result += data[i]; int consecutiveDigits = 0; - for (; i >= 0; --i) - { - if (unicodeLatinDigit (data[i])) - { + for (; i >= 0; --i) { + if (unicodeLatinDigit(data[i])) { result += data[i]; - if (++consecutiveDigits == 3 && i && unicodeLatinDigit (data[i - 1])) - { + if (++consecutiveDigits == 3 && i && unicodeLatinDigit(data[i - 1])) { result += ','; consecutiveDigits = 0; } - } - else + } else result += data[i]; } - } - else - { + } else { // In reverse order, transfer all digits up to, but not including the last // digit. - for (i = (int) data.length () - 1; i > end; --i) - result += data[i]; + for (i = (int)data.length() - 1; i > end; --i) result += data[i]; int consecutiveDigits = 0; - for (; i >= 0; --i) - { - if (unicodeLatinDigit (data[i])) - { + for (; i >= 0; --i) { + if (unicodeLatinDigit(data[i])) { result += data[i]; - if (++consecutiveDigits == 3 && i && unicodeLatinDigit (data[i - 1])) - { + if (++consecutiveDigits == 3 && i && unicodeLatinDigit(data[i - 1])) { result += ','; consecutiveDigits = 0; } - } - else + } else result += data[i]; } } // reverse result into data. std::string done; - for (int i = (int) result.length () - 1; i >= 0; --i) - done += result[i]; + for (int i = (int)result.length() - 1; i >= 0; --i) done += result[i]; return done; } //////////////////////////////////////////////////////////////////////////////// -std::string Lexer::lowerCase (const std::string& input) -{ +std::string Lexer::lowerCase(const std::string& input) { std::string output = input; - std::transform (output.begin (), output.end (), output.begin (), tolower); + std::transform(output.begin(), output.end(), output.begin(), tolower); return output; } //////////////////////////////////////////////////////////////////////////////// -std::string Lexer::ucFirst (const std::string& input) -{ +std::string Lexer::ucFirst(const std::string& input) { std::string output = input; - if (output.length () > 0) - output[0] = toupper (output[0]); + if (output.length() > 0) output[0] = toupper(output[0]); return output; } //////////////////////////////////////////////////////////////////////////////// -std::string Lexer::trimLeft (const std::string& in, const std::string& t /*= " "*/) -{ - std::string::size_type ws = in.find_first_not_of (t); - if (ws > 0) - { - std::string out {in}; - return out.erase (0, ws); +std::string Lexer::trimLeft(const std::string& in, const std::string& t /*= " "*/) { + std::string::size_type ws = in.find_first_not_of(t); + if (ws > 0) { + std::string out{in}; + return out.erase(0, ws); } return in; } //////////////////////////////////////////////////////////////////////////////// -std::string Lexer::trimRight (const std::string& in, const std::string& t /*= " "*/) -{ - std::string out {in}; - return out.erase (in.find_last_not_of (t) + 1); +std::string Lexer::trimRight(const std::string& in, const std::string& t /*= " "*/) { + std::string out{in}; + return out.erase(in.find_last_not_of(t) + 1); } //////////////////////////////////////////////////////////////////////////////// -std::string Lexer::trim (const std::string& in, const std::string& t /*= " "*/) -{ - return trimLeft (trimRight (in, t), t); +std::string Lexer::trim(const std::string& in, const std::string& t /*= " "*/) { + return trimLeft(trimRight(in, t), t); } //////////////////////////////////////////////////////////////////////////////// @@ -471,11 +387,9 @@ std::string Lexer::trim (const std::string& in, const std::string& t /*= " "*/) // '|" // [ U+XXXX | \uXXXX | \" | \' | \\ | \/ | \b | \f | \n | \r | \t | . ] // '|" -bool Lexer::isString (std::string& token, Lexer::Type& type, const std::string& quotes) -{ +bool Lexer::isString(std::string& token, Lexer::Type& type, const std::string& quotes) { std::size_t marker = _cursor; - if (readWord (_text, quotes, marker, token)) - { + if (readWord(_text, quotes, marker, token)) { type = Lexer::Type::string; _cursor = marker; return true; @@ -487,15 +401,13 @@ bool Lexer::isString (std::string& token, Lexer::Type& type, const std::string& //////////////////////////////////////////////////////////////////////////////// // Lexer::Type::date // -bool Lexer::isDate (std::string& token, Lexer::Type& type) -{ +bool Lexer::isDate(std::string& token, Lexer::Type& type) { // Try an ISO date parse. std::size_t iso_i = 0; Datetime iso; - if (iso.parse (_text.substr (_cursor), iso_i, Lexer::dateFormat)) - { + if (iso.parse(_text.substr(_cursor), iso_i, Lexer::dateFormat)) { type = Lexer::Type::date; - token = _text.substr (_cursor, iso_i); + token = _text.substr(_cursor, iso_i); _cursor += iso_i; return true; } @@ -506,24 +418,21 @@ bool Lexer::isDate (std::string& token, Lexer::Type& type) //////////////////////////////////////////////////////////////////////////////// // Lexer::Type::duration // -bool Lexer::isDuration (std::string& token, Lexer::Type& type) -{ +bool Lexer::isDuration(std::string& token, Lexer::Type& type) { std::size_t marker = _cursor; std::string extractedToken; Lexer::Type extractedType; - if (isOperator (extractedToken, extractedType)) - { + if (isOperator(extractedToken, extractedType)) { _cursor = marker; return false; } marker = 0; Duration iso; - if (iso.parse (_text.substr (_cursor), marker)) - { + if (iso.parse(_text.substr(_cursor), marker)) { type = Lexer::Type::duration; - token = _text.substr (_cursor, marker); + token = _text.substr(_cursor, marker); _cursor += marker; return true; } @@ -543,30 +452,22 @@ bool Lexer::isDuration (std::string& token, Lexer::Type& type) // XXXXXXXX- // XXXXXXXX // Followed only by EOS, whitespace, or single character operator. -bool Lexer::isUUID (std::string& token, Lexer::Type& type, bool endBoundary) -{ +bool Lexer::isUUID(std::string& token, Lexer::Type& type, bool endBoundary) { std::size_t marker = _cursor; // Greedy. std::size_t i = 0; - for (; i < 36 && marker + i < _eos; i++) - { - if (uuid_pattern[i] == 'x') - { - if (! unicodeHexDigit (_text[marker + i])) - break; - } - else if (uuid_pattern[i] != _text[marker + i]) + for (; i < 36 && marker + i < _eos; i++) { + if (uuid_pattern[i] == 'x') { + if (!unicodeHexDigit(_text[marker + i])) break; + } else if (uuid_pattern[i] != _text[marker + i]) break; } - if (i >= uuid_min_length && - (! endBoundary || - ! _text[marker + i] || - unicodeWhitespace (_text[marker + i]) || - isSingleCharOperator (_text[marker + i]))) - { - token = _text.substr (_cursor, i); + if (i >= uuid_min_length && + (!endBoundary || !_text[marker + i] || unicodeWhitespace(_text[marker + i]) || + isSingleCharOperator(_text[marker + i]))) { + token = _text.substr(_cursor, i); type = Lexer::Type::uuid; _cursor += i; return true; @@ -578,22 +479,16 @@ bool Lexer::isUUID (std::string& token, Lexer::Type& type, bool endBoundary) //////////////////////////////////////////////////////////////////////////////// // Lexer::Type::hex // 0xX+ -bool Lexer::isHexNumber (std::string& token, Lexer::Type& type) -{ +bool Lexer::isHexNumber(std::string& token, Lexer::Type& type) { std::size_t marker = _cursor; - if (_eos - marker >= 3 && - _text[marker + 0] == '0' && - _text[marker + 1] == 'x') - { + if (_eos - marker >= 3 && _text[marker + 0] == '0' && _text[marker + 1] == 'x') { marker += 2; - while (unicodeHexDigit (_text[marker])) - ++marker; + while (unicodeHexDigit(_text[marker])) ++marker; - if (marker - _cursor > 2) - { - token = _text.substr (_cursor, marker - _cursor); + if (marker - _cursor > 2) { + token = _text.substr(_cursor, marker - _cursor); type = Lexer::Type::hex; _cursor = marker; return true; @@ -610,57 +505,41 @@ bool Lexer::isHexNumber (std::string& token, Lexer::Type& type) // [ . \d+ ] // [ e|E [ +|- ] \d+ [ . \d+ ] ] // not followed by non-operator. -bool Lexer::isNumber (std::string& token, Lexer::Type& type) -{ +bool Lexer::isNumber(std::string& token, Lexer::Type& type) { std::size_t marker = _cursor; bool leading_zero = (_text[marker] == '0'); - if (unicodeLatinDigit (_text[marker])) - { + if (unicodeLatinDigit(_text[marker])) { ++marker; // Two (or more) digit number with a leading zero are not allowed - if (leading_zero && unicodeLatinDigit (_text[marker])) - return false; + if (leading_zero && unicodeLatinDigit(_text[marker])) return false; - while (unicodeLatinDigit (_text[marker])) - utf8_next_char (_text, marker); + while (unicodeLatinDigit(_text[marker])) utf8_next_char(_text, marker); - if (_text[marker] == '.') - { + if (_text[marker] == '.') { ++marker; - if (unicodeLatinDigit (_text[marker])) - { + if (unicodeLatinDigit(_text[marker])) { ++marker; - while (unicodeLatinDigit (_text[marker])) - utf8_next_char (_text, marker); + while (unicodeLatinDigit(_text[marker])) utf8_next_char(_text, marker); } } - if (_text[marker] == 'e' || - _text[marker] == 'E') - { + if (_text[marker] == 'e' || _text[marker] == 'E') { ++marker; - if (_text[marker] == '+' || - _text[marker] == '-') - ++marker; + if (_text[marker] == '+' || _text[marker] == '-') ++marker; - if (unicodeLatinDigit (_text[marker])) - { + if (unicodeLatinDigit(_text[marker])) { ++marker; - while (unicodeLatinDigit (_text[marker])) - utf8_next_char (_text, marker); + while (unicodeLatinDigit(_text[marker])) utf8_next_char(_text, marker); - if (_text[marker] == '.') - { + if (_text[marker] == '.') { ++marker; - if (unicodeLatinDigit (_text[marker])) - { + if (unicodeLatinDigit(_text[marker])) { ++marker; - while (unicodeLatinDigit (_text[marker])) - utf8_next_char (_text, marker); + while (unicodeLatinDigit(_text[marker])) utf8_next_char(_text, marker); } } } @@ -668,12 +547,10 @@ bool Lexer::isNumber (std::string& token, Lexer::Type& type) // Lookahead: ! | ! // If there is an immediately consecutive character, that is not an operator, fail. - if (_eos > marker && - ! unicodeWhitespace (_text[marker]) && - ! isSingleCharOperator (_text[marker])) + if (_eos > marker && !unicodeWhitespace(_text[marker]) && !isSingleCharOperator(_text[marker])) return false; - token = _text.substr (_cursor, marker - _cursor); + token = _text.substr(_cursor, marker - _cursor); type = Lexer::Type::number; _cursor = marker; return true; @@ -687,23 +564,19 @@ bool Lexer::isNumber (std::string& token, Lexer::Type& type) // 0 // [1-9]\d* // Integers do not start with a leading 0, unless they are zero. -bool Lexer::isInteger (std::string& token, Lexer::Type& type) -{ +bool Lexer::isInteger(std::string& token, Lexer::Type& type) { std::size_t marker = _cursor; bool leading_zero = (_text[marker] == '0'); - if (unicodeLatinDigit (_text[marker])) - { + if (unicodeLatinDigit(_text[marker])) { ++marker; - while (unicodeLatinDigit (_text[marker])) - utf8_next_char (_text, marker); + while (unicodeLatinDigit(_text[marker])) utf8_next_char(_text, marker); // Leading zero is only allowed in the case of number 0 - if (leading_zero and marker - _cursor > 1) - return false; + if (leading_zero and marker - _cursor > 1) return false; - token = _text.substr (_cursor, marker - _cursor); + token = _text.substr(_cursor, marker - _cursor); type = Lexer::Type::number; _cursor = marker; return true; @@ -715,12 +588,8 @@ bool Lexer::isInteger (std::string& token, Lexer::Type& type) //////////////////////////////////////////////////////////////////////////////// // Lexer::Type::separator // -- -bool Lexer::isSeparator (std::string& token, Lexer::Type& type) -{ - if (_eos - _cursor >= 2 && - _text[_cursor] == '-' && - _text[_cursor + 1] == '-') - { +bool Lexer::isSeparator(std::string& token, Lexer::Type& type) { + if (_eos - _cursor >= 2 && _text[_cursor] == '-' && _text[_cursor + 1] == '-') { _cursor += 2; type = Lexer::Type::separator; token = "--"; @@ -733,31 +602,23 @@ bool Lexer::isSeparator (std::string& token, Lexer::Type& type) //////////////////////////////////////////////////////////////////////////////// // Lexer::Type::url // http [s] :// ... -bool Lexer::isURL (std::string& token, Lexer::Type& type) -{ +bool Lexer::isURL(std::string& token, Lexer::Type& type) { std::size_t marker = _cursor; - if (_eos - _cursor > 9 && // length 'https://*' + if (_eos - _cursor > 9 && // length 'https://*' (_text[marker + 0] == 'h' || _text[marker + 0] == 'H') && (_text[marker + 1] == 't' || _text[marker + 1] == 'T') && (_text[marker + 2] == 't' || _text[marker + 2] == 'T') && - (_text[marker + 3] == 'p' || _text[marker + 3] == 'P')) - { + (_text[marker + 3] == 'p' || _text[marker + 3] == 'P')) { marker += 4; - if (_text[marker + 0] == 's' || _text[marker + 0] == 'S') - ++marker; + if (_text[marker + 0] == 's' || _text[marker + 0] == 'S') ++marker; - if (_text[marker + 0] == ':' && - _text[marker + 1] == '/' && - _text[marker + 2] == '/') - { + if (_text[marker + 0] == ':' && _text[marker + 1] == '/' && _text[marker + 2] == '/') { marker += 3; - while (marker < _eos && - ! unicodeWhitespace (_text[marker])) - utf8_next_char (_text, marker); + while (marker < _eos && !unicodeWhitespace(_text[marker])) utf8_next_char(_text, marker); - token = _text.substr (_cursor, marker - _cursor); + token = _text.substr(_cursor, marker - _cursor); type = Lexer::Type::url; _cursor = marker; return true; @@ -771,33 +632,27 @@ bool Lexer::isURL (std::string& token, Lexer::Type& type) // Lexer::Type::pair // [ | ] // separator '::' | ':=' | ':' | '=' -bool Lexer::isPair (std::string& token, Lexer::Type& type) -{ +bool Lexer::isPair(std::string& token, Lexer::Type& type) { std::size_t marker = _cursor; std::string ignoredToken; Lexer::Type ignoredType; - if (isIdentifier (ignoredToken, ignoredType)) - { + if (isIdentifier(ignoredToken, ignoredType)) { // Look for a valid separator. - std::string separator = _text.substr (_cursor, 2); + std::string separator = _text.substr(_cursor, 2); if (separator == "::" || separator == ":=") _cursor += 2; else if (separator[0] == ':' || separator[0] == '=') _cursor++; - else - { + else { _cursor = marker; return false; } // String, word or nothing are all valid. - if (readWord (_text, "'\"", _cursor, ignoredToken) || - readWord (_text, _cursor, ignoredToken) || - isEOS () || - unicodeWhitespace (_text[_cursor])) - { - token = _text.substr (marker, _cursor - marker); + if (readWord(_text, "'\"", _cursor, ignoredToken) || readWord(_text, _cursor, ignoredToken) || + isEOS() || unicodeWhitespace(_text[_cursor])) { + token = _text.substr(marker, _cursor - marker); type = Lexer::Type::pair; return true; } @@ -815,81 +670,62 @@ bool Lexer::isPair (std::string& token, Lexer::Type& type) // or a combination: 1,3,5-10 // // [ - ] [ , [ - ] ] ... -bool Lexer::isSet (std::string& token, Lexer::Type& type) -{ +bool Lexer::isSet(std::string& token, Lexer::Type& type) { std::size_t marker = _cursor; int count = 0; std::string dummyToken; Lexer::Type dummyType; - do - { - if (isInteger (dummyToken, dummyType)) - { + do { + if (isInteger(dummyToken, dummyType)) { ++count; - if (isLiteral ("-", false, false)) - { - if (isInteger (dummyToken, dummyType)) + if (isLiteral("-", false, false)) { + if (isInteger(dummyToken, dummyType)) ++count; - else - { + else { _cursor = marker; return false; } } - } - else - { + } else { _cursor = marker; return false; } - } - while (isLiteral (",", false, false)); + } while (isLiteral(",", false, false)); // Success is multiple numbers, matching the pattern. - if (count > 1 && - (isEOS () || - unicodeWhitespace (_text[_cursor]) || - isHardBoundary (_text[_cursor], _text[_cursor + 1]))) - { - token = _text.substr (marker, _cursor - marker); + if (count > 1 && (isEOS() || unicodeWhitespace(_text[_cursor]) || + isHardBoundary(_text[_cursor], _text[_cursor + 1]))) { + token = _text.substr(marker, _cursor - marker); type = Lexer::Type::set; return true; } _cursor = marker; return false; - } //////////////////////////////////////////////////////////////////////////////// // Lexer::Type::tag // ^ | '(' | ')' | // [ +|- ] [ ]* -bool Lexer::isTag (std::string& token, Lexer::Type& type) -{ +bool Lexer::isTag(std::string& token, Lexer::Type& type) { std::size_t marker = _cursor; // Lookbehind: Assert ^ or preceded by whitespace, (, or ). - if (marker > 0 && - ! unicodeWhitespace (_text[marker - 1]) && - _text[marker - 1] != '(' && + if (marker > 0 && !unicodeWhitespace(_text[marker - 1]) && _text[marker - 1] != '(' && _text[marker - 1] != ')') return false; - if (_text[marker] == '+' || - _text[marker] == '-') - { + if (_text[marker] == '+' || _text[marker] == '-') { ++marker; - if (isIdentifierStart (_text[marker])) - { - utf8_next_char (_text, marker); + if (isIdentifierStart(_text[marker])) { + utf8_next_char(_text, marker); - while (isIdentifierNext (_text[marker])) - utf8_next_char (_text, marker); + while (isIdentifierNext(_text[marker])) utf8_next_char(_text, marker); - token = _text.substr (_cursor, marker - _cursor); + token = _text.substr(_cursor, marker - _cursor); type = Lexer::Type::tag; _cursor = marker; return true; @@ -902,40 +738,28 @@ bool Lexer::isTag (std::string& token, Lexer::Type& type) //////////////////////////////////////////////////////////////////////////////// // Lexer::Type::path // ( / )+ -bool Lexer::isPath (std::string& token, Lexer::Type& type) -{ +bool Lexer::isPath(std::string& token, Lexer::Type& type) { std::size_t marker = _cursor; int slashCount = 0; - while (true) - { - if (_text[marker] == '/') - { + while (true) { + if (_text[marker] == '/') { ++marker; ++slashCount; - } - else + } else break; - if (_text[marker] && - ! unicodeWhitespace (_text[marker]) && - _text[marker] != '/') - { - utf8_next_char (_text, marker); - while (_text[marker] && - ! unicodeWhitespace (_text[marker]) && - _text[marker] != '/') - utf8_next_char (_text, marker); - } - else + if (_text[marker] && !unicodeWhitespace(_text[marker]) && _text[marker] != '/') { + utf8_next_char(_text, marker); + while (_text[marker] && !unicodeWhitespace(_text[marker]) && _text[marker] != '/') + utf8_next_char(_text, marker); + } else break; } - if (marker > _cursor && - slashCount > 3) - { + if (marker > _cursor && slashCount > 3) { type = Lexer::Type::path; - token = _text.substr (_cursor, marker - _cursor); + token = _text.substr(_cursor, marker - _cursor); _cursor = marker; return true; } @@ -946,25 +770,19 @@ bool Lexer::isPath (std::string& token, Lexer::Type& type) //////////////////////////////////////////////////////////////////////////////// // Lexer::Type::substitution // / / / [g] | -bool Lexer::isSubstitution (std::string& token, Lexer::Type& type) -{ +bool Lexer::isSubstitution(std::string& token, Lexer::Type& type) { std::size_t marker = _cursor; std::string word; - if (readWord (_text, "/", _cursor, word)) - { + if (readWord(_text, "/", _cursor, word)) { --_cursor; // Step backwards over the '/'. - if (readWord (_text, "/", _cursor, word)) - { - if (_text[_cursor] == 'g') - ++_cursor; + if (readWord(_text, "/", _cursor, word)) { + if (_text[_cursor] == 'g') ++_cursor; // Lookahread: | - if (_text[_cursor] == '\0' || - unicodeWhitespace (_text[_cursor])) - { - token = _text.substr (marker, _cursor - marker); + if (_text[_cursor] == '\0' || unicodeWhitespace(_text[_cursor])) { + token = _text.substr(marker, _cursor - marker); type = Lexer::Type::substitution; return true; } @@ -978,16 +796,12 @@ bool Lexer::isSubstitution (std::string& token, Lexer::Type& type) //////////////////////////////////////////////////////////////////////////////// // Lexer::Type::pattern // / / | -bool Lexer::isPattern (std::string& token, Lexer::Type& type) -{ +bool Lexer::isPattern(std::string& token, Lexer::Type& type) { std::size_t marker = _cursor; std::string word; - if (readWord (_text, "/", _cursor, word) && - (isEOS () || - unicodeWhitespace (_text[_cursor]))) - { - token = _text.substr (marker, _cursor - marker); + if (readWord(_text, "/", _cursor, word) && (isEOS() || unicodeWhitespace(_text[_cursor]))) { + token = _text.substr(marker, _cursor - marker); type = Lexer::Type::pattern; return true; } @@ -1002,68 +816,60 @@ bool Lexer::isPattern (std::string& token, Lexer::Type& type) // | // | // | -bool Lexer::isOperator (std::string& token, Lexer::Type& type) -{ +bool Lexer::isOperator(std::string& token, Lexer::Type& type) { std::size_t marker = _cursor; - if (_eos - marker >= 8 && _text.substr (marker, 8) == "_hastag_") - { + if (_eos - marker >= 8 && _text.substr(marker, 8) == "_hastag_") { marker += 8; type = Lexer::Type::op; - token = _text.substr (_cursor, marker - _cursor); + token = _text.substr(_cursor, marker - _cursor); _cursor = marker; return true; } - else if (_eos - marker >= 7 && _text.substr (marker, 7) == "_notag_") - { + else if (_eos - marker >= 7 && _text.substr(marker, 7) == "_notag_") { marker += 7; type = Lexer::Type::op; - token = _text.substr (_cursor, marker - _cursor); + token = _text.substr(_cursor, marker - _cursor); _cursor = marker; return true; } - else if (_eos - marker >= 5 && _text.substr (marker, 5) == "_neg_") - { + else if (_eos - marker >= 5 && _text.substr(marker, 5) == "_neg_") { marker += 5; type = Lexer::Type::op; - token = _text.substr (_cursor, marker - _cursor); + token = _text.substr(_cursor, marker - _cursor); _cursor = marker; return true; } - else if (_eos - marker >= 5 && _text.substr (marker, 5) == "_pos_") - { + else if (_eos - marker >= 5 && _text.substr(marker, 5) == "_pos_") { marker += 5; type = Lexer::Type::op; - token = _text.substr (_cursor, marker - _cursor); + token = _text.substr(_cursor, marker - _cursor); _cursor = marker; return true; } - else if (_eos - marker >= 3 && - isTripleCharOperator (_text[marker], _text[marker + 1], _text[marker + 2], _text[marker + 3])) - { + else if (_eos - marker >= 3 && isTripleCharOperator(_text[marker], _text[marker + 1], + _text[marker + 2], _text[marker + 3])) { marker += 3; type = Lexer::Type::op; - token = _text.substr (_cursor, marker - _cursor); + token = _text.substr(_cursor, marker - _cursor); _cursor = marker; return true; } else if (_eos - marker >= 2 && - isDoubleCharOperator (_text[marker], _text[marker + 1], _text[marker + 2])) - { + isDoubleCharOperator(_text[marker], _text[marker + 1], _text[marker + 2])) { marker += 2; type = Lexer::Type::op; - token = _text.substr (_cursor, marker - _cursor); + token = _text.substr(_cursor, marker - _cursor); _cursor = marker; return true; } - else if (isSingleCharOperator (_text[marker])) - { + else if (isSingleCharOperator(_text[marker])) { token = _text[marker]; type = Lexer::Type::op; _cursor = ++marker; @@ -1117,38 +923,25 @@ bool Lexer::isOperator (std::string& token, Lexer::Type& type) // annotations..entry // annotations..description // -bool Lexer::isDOM (std::string& token, Lexer::Type& type) -{ +bool Lexer::isDOM(std::string& token, Lexer::Type& type) { std::size_t marker = _cursor; // rc. ... std::string partialToken; Lexer::Type partialType; - if (isLiteral ("rc.", false, false) && - isWord (partialToken, partialType)) - { - token = _text.substr (marker, _cursor - marker); + if (isLiteral("rc.", false, false) && isWord(partialToken, partialType)) { + token = _text.substr(marker, _cursor - marker); type = Lexer::Type::dom; return true; - } - else + } else _cursor = marker; // Literals - if (isOneOf ({"tw.syncneeded", - "tw.program", - "tw.args", - "tw.width", - "tw.height", - "tw.version", - "context.program", - "context.args", - "context.width", - "context.height", - "system.version", - "system.os"}, false, true)) - { - token = _text.substr (marker, _cursor - marker); + if (isOneOf({"tw.syncneeded", "tw.program", "tw.args", "tw.width", "tw.height", "tw.version", + "context.program", "context.args", "context.width", "context.height", + "system.version", "system.os"}, + false, true)) { + token = _text.substr(marker, _cursor - marker); type = Lexer::Type::dom; return true; } @@ -1158,11 +951,8 @@ bool Lexer::isDOM (std::string& token, Lexer::Type& type) // . std::string extractedToken; Lexer::Type extractedType; - if (isUUID (extractedToken, extractedType, false) || - isInteger (extractedToken, extractedType)) - { - if (! isLiteral (".", false, false)) - { + if (isUUID(extractedToken, extractedType, false) || isInteger(extractedToken, extractedType)) { + if (!isLiteral(".", false, false)) { _cursor = marker; return false; } @@ -1172,40 +962,31 @@ bool Lexer::isDOM (std::string& token, Lexer::Type& type) std::size_t checkpoint = _cursor; // [prefix]tags. - if (isLiteral ("tags", false, false) && - isLiteral (".", false, false) && - isWord (partialToken, partialType)) - { - token = _text.substr (marker, _cursor - marker); + if (isLiteral("tags", false, false) && isLiteral(".", false, false) && + isWord(partialToken, partialType)) { + token = _text.substr(marker, _cursor - marker); type = Lexer::Type::dom; return true; - } - else + } else _cursor = checkpoint; // [prefix]attribute (bounded) - if (isOneOf (attributes, false, true)) - { - token = _text.substr (marker, _cursor - marker); + if (isOneOf(attributes, false, true)) { + token = _text.substr(marker, _cursor - marker); type = Lexer::Type::dom; return true; } // [prefix]attribute. (unbounded) - if (isOneOf (attributes, false, false)) - { - if (isLiteral (".", false, false)) - { - std::string attribute = _text.substr (checkpoint, _cursor - checkpoint - 1); + if (isOneOf(attributes, false, false)) { + if (isLiteral(".", false, false)) { + std::string attribute = _text.substr(checkpoint, _cursor - checkpoint - 1); // if attribute type is 'date', then it has sub-elements. if (attributes[attribute] == "date" && - isOneOf ({"year", "month", "day", - "week", "weekday", - "julian", - "hour", "minute", "second"}, false, true)) - { - token = _text.substr (marker, _cursor - marker); + isOneOf({"year", "month", "day", "week", "weekday", "julian", "hour", "minute", "second"}, + false, true)) { + token = _text.substr(marker, _cursor - marker); type = Lexer::Type::dom; return true; } @@ -1214,9 +995,8 @@ bool Lexer::isDOM (std::string& token, Lexer::Type& type) } // Lookahead: ! - else if (! unicodeLatinAlpha (_text[marker])) - { - token = _text.substr (marker, _cursor - marker); + else if (!unicodeLatinAlpha(_text[marker])) { + token = _text.substr(marker, _cursor - marker); type = Lexer::Type::dom; return true; } @@ -1225,48 +1005,35 @@ bool Lexer::isDOM (std::string& token, Lexer::Type& type) } // [prefix]annotations. - if (isLiteral ("annotations", true, false) && - isLiteral (".", false, false)) - { - if (isLiteral ("count", false, false)) - { - token = _text.substr (marker, _cursor - marker); + if (isLiteral("annotations", true, false) && isLiteral(".", false, false)) { + if (isLiteral("count", false, false)) { + token = _text.substr(marker, _cursor - marker); type = Lexer::Type::dom; return true; } std::string extractedToken; Lexer::Type extractedType; - if (isInteger (extractedToken, extractedType)) - { - if (isLiteral (".", false, false)) - { - if (isLiteral ("description", false, true)) - { - token = _text.substr (marker, _cursor - marker); + if (isInteger(extractedToken, extractedType)) { + if (isLiteral(".", false, false)) { + if (isLiteral("description", false, true)) { + token = _text.substr(marker, _cursor - marker); type = Lexer::Type::dom; return true; - } - else if (isLiteral ("entry", false, true)) - { - token = _text.substr (marker, _cursor - marker); + } else if (isLiteral("entry", false, true)) { + token = _text.substr(marker, _cursor - marker); type = Lexer::Type::dom; return true; - } - else if (isLiteral ("entry", false, false) && - isLiteral (".", false, false) && - isOneOf ({"year", "month", "day", - "week", "weekday", - "julian", - "hour", "minute", "second"}, false, true)) - { - token = _text.substr (marker, _cursor - marker); + } else if (isLiteral("entry", false, false) && isLiteral(".", false, false) && + isOneOf({"year", "month", "day", "week", "weekday", "julian", "hour", "minute", + "second"}, + false, true)) { + token = _text.substr(marker, _cursor - marker); type = Lexer::Type::dom; return true; } } - } - else + } else _cursor = checkpoint; } @@ -1277,18 +1044,15 @@ bool Lexer::isDOM (std::string& token, Lexer::Type& type) //////////////////////////////////////////////////////////////////////////////// // Lexer::Type::identifier // [ ]* -bool Lexer::isIdentifier (std::string& token, Lexer::Type& type) -{ +bool Lexer::isIdentifier(std::string& token, Lexer::Type& type) { std::size_t marker = _cursor; - if (isIdentifierStart (_text[marker])) - { - utf8_next_char (_text, marker); + if (isIdentifierStart(_text[marker])) { + utf8_next_char(_text, marker); - while (isIdentifierNext (_text[marker])) - utf8_next_char (_text, marker); + while (isIdentifierNext(_text[marker])) utf8_next_char(_text, marker); - token = _text.substr (_cursor, marker - _cursor); + token = _text.substr(_cursor, marker - _cursor); type = Lexer::Type::identifier; _cursor = marker; return true; @@ -1300,18 +1064,14 @@ bool Lexer::isIdentifier (std::string& token, Lexer::Type& type) //////////////////////////////////////////////////////////////////////////////// // Lexer::Type::word // [^\s]+ -bool Lexer::isWord (std::string& token, Lexer::Type& type) -{ +bool Lexer::isWord(std::string& token, Lexer::Type& type) { std::size_t marker = _cursor; - while (_text[marker] && - ! unicodeWhitespace (_text[marker]) && - ! isSingleCharOperator (_text[marker])) - utf8_next_char (_text, marker); + while (_text[marker] && !unicodeWhitespace(_text[marker]) && !isSingleCharOperator(_text[marker])) + utf8_next_char(_text, marker); - if (marker > _cursor) - { - token = _text.substr (_cursor, marker - _cursor); + if (marker > _cursor) { + token = _text.substr(_cursor, marker - _cursor); type = Lexer::Type::word; _cursor = marker; return true; @@ -1321,28 +1081,18 @@ bool Lexer::isWord (std::string& token, Lexer::Type& type) } //////////////////////////////////////////////////////////////////////////////// -bool Lexer::isLiteral ( - const std::string& literal, - bool allowAbbreviations, - bool endBoundary) -{ - auto common = commonLength (literal, 0, _text, _cursor); +bool Lexer::isLiteral(const std::string& literal, bool allowAbbreviations, bool endBoundary) { + auto common = commonLength(literal, 0, _text, _cursor); // Without abbreviations, common must equal literal length. - if (! allowAbbreviations && - common < literal.length ()) - return false; + if (!allowAbbreviations && common < literal.length()) return false; // Abbreviations must meet the minimum size. - if (allowAbbreviations && - common < minimumMatchLength) - return false; + if (allowAbbreviations && common < minimumMatchLength) return false; // End boundary conditions must be met. - if (endBoundary && - _text[_cursor + common] && - ! unicodeWhitespace (_text[_cursor + common]) && - ! Lexer::isSingleCharOperator (_text[_cursor + common])) + if (endBoundary && _text[_cursor + common] && !unicodeWhitespace(_text[_cursor + common]) && + !Lexer::isSingleCharOperator(_text[_cursor + common])) return false; _cursor += common; @@ -1350,76 +1100,81 @@ bool Lexer::isLiteral ( } //////////////////////////////////////////////////////////////////////////////// -bool Lexer::isOneOf ( - const std::vector & options, - bool allowAbbreviations, - bool endBoundary) -{ +bool Lexer::isOneOf(const std::vector& options, bool allowAbbreviations, + bool endBoundary) { for (auto& item : options) - if (isLiteral (item, allowAbbreviations, endBoundary)) - return true; + if (isLiteral(item, allowAbbreviations, endBoundary)) return true; return false; } //////////////////////////////////////////////////////////////////////////////// -bool Lexer::isOneOf ( - const std::map & options, - bool allowAbbreviations, - bool endBoundary) -{ +bool Lexer::isOneOf(const std::map& options, bool allowAbbreviations, + bool endBoundary) { for (auto& item : options) - if (isLiteral (item.first, allowAbbreviations, endBoundary)) - return true; + if (isLiteral(item.first, allowAbbreviations, endBoundary)) return true; return false; } //////////////////////////////////////////////////////////////////////////////// // Static -std::string Lexer::typeToString (Lexer::Type type) -{ - if (type == Lexer::Type::string) return std::string ("\033[38;5;7m\033[48;5;3m") + "string" + "\033[0m"; - else if (type == Lexer::Type::uuid) return std::string ("\033[38;5;7m\033[48;5;10m") + "uuid" + "\033[0m"; - else if (type == Lexer::Type::hex) return std::string ("\033[38;5;7m\033[48;5;14m") + "hex" + "\033[0m"; - else if (type == Lexer::Type::number) return std::string ("\033[38;5;7m\033[48;5;6m") + "number" + "\033[0m"; - else if (type == Lexer::Type::separator) return std::string ("\033[38;5;7m\033[48;5;4m") + "separator" + "\033[0m"; - else if (type == Lexer::Type::url) return std::string ("\033[38;5;7m\033[48;5;4m") + "url" + "\033[0m"; - else if (type == Lexer::Type::pair) return std::string ("\033[38;5;7m\033[48;5;1m") + "pair" + "\033[0m"; - else if (type == Lexer::Type::set) return std::string ("\033[38;5;15m\033[48;5;208m") + "set" + "\033[0m"; - else if (type == Lexer::Type::tag) return std::string ("\033[37;45m") + "tag" + "\033[0m"; - else if (type == Lexer::Type::path) return std::string ("\033[37;102m") + "path" + "\033[0m"; - else if (type == Lexer::Type::substitution) return std::string ("\033[37;102m") + "substitution" + "\033[0m"; - else if (type == Lexer::Type::pattern) return std::string ("\033[37;42m") + "pattern" + "\033[0m"; - else if (type == Lexer::Type::op) return std::string ("\033[38;5;7m\033[48;5;203m") + "op" + "\033[0m"; - else if (type == Lexer::Type::dom) return std::string ("\033[38;5;15m\033[48;5;244m") + "dom" + "\033[0m"; - else if (type == Lexer::Type::identifier) return std::string ("\033[38;5;15m\033[48;5;244m") + "identifier" + "\033[0m"; - else if (type == Lexer::Type::word) return std::string ("\033[38;5;15m\033[48;5;236m") + "word" + "\033[0m"; - else if (type == Lexer::Type::date) return std::string ("\033[38;5;15m\033[48;5;34m") + "date" + "\033[0m"; - else if (type == Lexer::Type::duration) return std::string ("\033[38;5;15m\033[48;5;34m") + "duration" + "\033[0m"; - else return std::string ("\033[37;41m") + "unknown" + "\033[0m"; +std::string Lexer::typeToString(Lexer::Type type) { + if (type == Lexer::Type::string) + return std::string("\033[38;5;7m\033[48;5;3m") + "string" + "\033[0m"; + else if (type == Lexer::Type::uuid) + return std::string("\033[38;5;7m\033[48;5;10m") + "uuid" + "\033[0m"; + else if (type == Lexer::Type::hex) + return std::string("\033[38;5;7m\033[48;5;14m") + "hex" + "\033[0m"; + else if (type == Lexer::Type::number) + return std::string("\033[38;5;7m\033[48;5;6m") + "number" + "\033[0m"; + else if (type == Lexer::Type::separator) + return std::string("\033[38;5;7m\033[48;5;4m") + "separator" + "\033[0m"; + else if (type == Lexer::Type::url) + return std::string("\033[38;5;7m\033[48;5;4m") + "url" + "\033[0m"; + else if (type == Lexer::Type::pair) + return std::string("\033[38;5;7m\033[48;5;1m") + "pair" + "\033[0m"; + else if (type == Lexer::Type::set) + return std::string("\033[38;5;15m\033[48;5;208m") + "set" + "\033[0m"; + else if (type == Lexer::Type::tag) + return std::string("\033[37;45m") + "tag" + "\033[0m"; + else if (type == Lexer::Type::path) + return std::string("\033[37;102m") + "path" + "\033[0m"; + else if (type == Lexer::Type::substitution) + return std::string("\033[37;102m") + "substitution" + "\033[0m"; + else if (type == Lexer::Type::pattern) + return std::string("\033[37;42m") + "pattern" + "\033[0m"; + else if (type == Lexer::Type::op) + return std::string("\033[38;5;7m\033[48;5;203m") + "op" + "\033[0m"; + else if (type == Lexer::Type::dom) + return std::string("\033[38;5;15m\033[48;5;244m") + "dom" + "\033[0m"; + else if (type == Lexer::Type::identifier) + return std::string("\033[38;5;15m\033[48;5;244m") + "identifier" + "\033[0m"; + else if (type == Lexer::Type::word) + return std::string("\033[38;5;15m\033[48;5;236m") + "word" + "\033[0m"; + else if (type == Lexer::Type::date) + return std::string("\033[38;5;15m\033[48;5;34m") + "date" + "\033[0m"; + else if (type == Lexer::Type::duration) + return std::string("\033[38;5;15m\033[48;5;34m") + "duration" + "\033[0m"; + else + return std::string("\033[37;41m") + "unknown" + "\033[0m"; } //////////////////////////////////////////////////////////////////////////////// -bool Lexer::isAllDigits (const std::string& text) -{ - return text.length () && - text.find_first_not_of ("0123456789") == std::string::npos; +bool Lexer::isAllDigits(const std::string& text) { + return text.length() && text.find_first_not_of("0123456789") == std::string::npos; } //////////////////////////////////////////////////////////////////////////////// // This is intentionally looking for a single token. -bool Lexer::isDOM (const std::string& text) -{ - Lexer lex (text); +bool Lexer::isDOM(const std::string& text) { + Lexer lex(text); int count = 0; std::string token; Lexer::Type type; - while (lex.token (token, type)) - ++count; + while (lex.token(token, type)) ++count; - return count == 1 && - type == Lexer::Type::dom; + return count == 1 && type == Lexer::Type::dom; } //////////////////////////////////////////////////////////////////////////////// @@ -1430,80 +1185,92 @@ bool Lexer::isDOM (const std::string& text) // "\"" // 'one two' // Result includes the quotes. -bool Lexer::readWord ( - const std::string& text, - const std::string& quotes, - std::string::size_type& cursor, - std::string& word) -{ - if (quotes.find (text[cursor]) == std::string::npos) - return false; +bool Lexer::readWord(const std::string& text, const std::string& quotes, + std::string::size_type& cursor, std::string& word) { + if (quotes.find(text[cursor]) == std::string::npos) return false; - std::string::size_type eos = text.length (); + std::string::size_type eos = text.length(); int quote = text[cursor++]; word = quote; int c; - while ((c = text[cursor])) - { + while ((c = text[cursor])) { // Quoted word ends on a quote. - if (quote && quote == c) - { - word += utf8_character (utf8_next_char (text, cursor)); + if (quote && quote == c) { + word += utf8_character(utf8_next_char(text, cursor)); break; } // Unicode U+XXXX or \uXXXX codepoint. else if (eos - cursor >= 6 && - ((text[cursor + 0] == 'U' && text[cursor + 1] == '+') || + ((text[cursor + 0] == 'U' && text[cursor + 1] == '+') || (text[cursor + 0] == '\\' && text[cursor + 1] == 'u')) && - unicodeHexDigit (text[cursor + 2]) && - unicodeHexDigit (text[cursor + 3]) && - unicodeHexDigit (text[cursor + 4]) && - unicodeHexDigit (text[cursor + 5])) - { - word += utf8_character ( - hexToInt ( - text[cursor + 2], - text[cursor + 3], - text[cursor + 4], - text[cursor + 5])); + unicodeHexDigit(text[cursor + 2]) && unicodeHexDigit(text[cursor + 3]) && + unicodeHexDigit(text[cursor + 4]) && unicodeHexDigit(text[cursor + 5])) { + word += utf8_character( + hexToInt(text[cursor + 2], text[cursor + 3], text[cursor + 4], text[cursor + 5])); cursor += 6; } // An escaped thing. - else if (c == '\\') - { + else if (c == '\\') { c = text[++cursor]; - switch (c) - { - case '"': word += (char) 0x22; ++cursor; break; - case '\'': word += (char) 0x27; ++cursor; break; - case '\\': word += (char) 0x5C; ++cursor; break; - case 'b': word += (char) 0x08; ++cursor; break; - case 'f': word += (char) 0x0C; ++cursor; break; - case 'n': word += (char) 0x0A; ++cursor; break; - case 'r': word += (char) 0x0D; ++cursor; break; - case 't': word += (char) 0x09; ++cursor; break; - case 'v': word += (char) 0x0B; ++cursor; break; + switch (c) { + case '"': + word += (char)0x22; + ++cursor; + break; + case '\'': + word += (char)0x27; + ++cursor; + break; + case '\\': + word += (char)0x5C; + ++cursor; + break; + case 'b': + word += (char)0x08; + ++cursor; + break; + case 'f': + word += (char)0x0C; + ++cursor; + break; + case 'n': + word += (char)0x0A; + ++cursor; + break; + case 'r': + word += (char)0x0D; + ++cursor; + break; + case 't': + word += (char)0x09; + ++cursor; + break; + case 'v': + word += (char)0x0B; + ++cursor; + break; - // This pass-through default case means that anything can be escaped - // harmlessly. In particular 'quote' is included, if it not one of the - // above characters. - default: word += (char) c; ++cursor; break; + // This pass-through default case means that anything can be escaped + // harmlessly. In particular 'quote' is included, if it not one of the + // above characters. + default: + word += (char)c; + ++cursor; + break; } } // Ordinary character. else - word += utf8_character (utf8_next_char (text, cursor)); + word += utf8_character(utf8_next_char(text, cursor)); } // Verify termination. - return word[0] == quote && - word[word.length () - 1] == quote && - word.length () >= 2; + return word[0] == quote && word[word.length() - 1] == quote && word.length() >= 2; } //////////////////////////////////////////////////////////////////////////////// @@ -1517,12 +1284,8 @@ bool Lexer::readWord ( // Lexer::isEOS // unicodeWhitespace // Lexer::isHardBoundary -bool Lexer::readWord ( - const std::string& text, - std::string::size_type& cursor, - std::string& word) -{ - std::string::size_type eos = text.length (); +bool Lexer::readWord(const std::string& text, std::string::size_type& cursor, std::string& word) { + std::string::size_type eos = text.length(); word = ""; int c; @@ -1530,139 +1293,140 @@ bool Lexer::readWord ( while ((c = text[cursor])) // Handles EOS. { // Unquoted word ends on white space. - if (unicodeWhitespace (c)) - break; + if (unicodeWhitespace(c)) break; // Parentheses mostly. - if (prev && Lexer::isHardBoundary (prev, c)) - break; + if (prev && Lexer::isHardBoundary(prev, c)) break; // Unicode U+XXXX or \uXXXX codepoint. else if (eos - cursor >= 6 && - ((text[cursor + 0] == 'U' && text[cursor + 1] == '+') || + ((text[cursor + 0] == 'U' && text[cursor + 1] == '+') || (text[cursor + 0] == '\\' && text[cursor + 1] == 'u')) && - unicodeHexDigit (text[cursor + 2]) && - unicodeHexDigit (text[cursor + 3]) && - unicodeHexDigit (text[cursor + 4]) && - unicodeHexDigit (text[cursor + 5])) - { - word += utf8_character ( - hexToInt ( - text[cursor + 2], - text[cursor + 3], - text[cursor + 4], - text[cursor + 5])); + unicodeHexDigit(text[cursor + 2]) && unicodeHexDigit(text[cursor + 3]) && + unicodeHexDigit(text[cursor + 4]) && unicodeHexDigit(text[cursor + 5])) { + word += utf8_character( + hexToInt(text[cursor + 2], text[cursor + 3], text[cursor + 4], text[cursor + 5])); cursor += 6; } // An escaped thing. - else if (c == '\\') - { + else if (c == '\\') { c = text[++cursor]; - switch (c) - { - case '"': word += (char) 0x22; ++cursor; break; - case '\'': word += (char) 0x27; ++cursor; break; - case '\\': word += (char) 0x5C; ++cursor; break; - case 'b': word += (char) 0x08; ++cursor; break; - case 'f': word += (char) 0x0C; ++cursor; break; - case 'n': word += (char) 0x0A; ++cursor; break; - case 'r': word += (char) 0x0D; ++cursor; break; - case 't': word += (char) 0x09; ++cursor; break; - case 'v': word += (char) 0x0B; ++cursor; break; + switch (c) { + case '"': + word += (char)0x22; + ++cursor; + break; + case '\'': + word += (char)0x27; + ++cursor; + break; + case '\\': + word += (char)0x5C; + ++cursor; + break; + case 'b': + word += (char)0x08; + ++cursor; + break; + case 'f': + word += (char)0x0C; + ++cursor; + break; + case 'n': + word += (char)0x0A; + ++cursor; + break; + case 'r': + word += (char)0x0D; + ++cursor; + break; + case 't': + word += (char)0x09; + ++cursor; + break; + case 'v': + word += (char)0x0B; + ++cursor; + break; - // This pass-through default case means that anything can be escaped - // harmlessly. In particular 'quote' is included, if it not one of the - // above characters. - default: word += (char) c; ++cursor; break; + // This pass-through default case means that anything can be escaped + // harmlessly. In particular 'quote' is included, if it not one of the + // above characters. + default: + word += (char)c; + ++cursor; + break; } } // Ordinary character. else - word += utf8_character (utf8_next_char (text, cursor)); + word += utf8_character(utf8_next_char(text, cursor)); prev = c; } - return word.length () > 0 ? true : false; + return word.length() > 0 ? true : false; } //////////////////////////////////////////////////////////////////////////////// // [. ] <: | = | :: | :=> [] -bool Lexer::decomposePair ( - const std::string& text, - std::string& name, - std::string& modifier, - std::string& separator, - std::string& value) -{ +bool Lexer::decomposePair(const std::string& text, std::string& name, std::string& modifier, + std::string& separator, std::string& value) { // Look for the required elements. - std::string::size_type dot = text.find ('.'); - std::string::size_type sep_defer = text.find ("::"); - std::string::size_type sep_eval = text.find (":="); - std::string::size_type sep_colon = text.find (':'); - std::string::size_type sep_equal = text.find ('='); + std::string::size_type dot = text.find('.'); + std::string::size_type sep_defer = text.find("::"); + std::string::size_type sep_eval = text.find(":="); + std::string::size_type sep_colon = text.find(':'); + std::string::size_type sep_equal = text.find('='); // Determine which separator is dominant, which would be the first one seen, // taking into consideration the overlapping : characters. - std::string::size_type sep = std::string::npos; + std::string::size_type sep = std::string::npos; std::string::size_type sep_end = std::string::npos; - if (sep_defer != std::string::npos && - (sep_eval == std::string::npos || sep_defer <= sep_eval) && + if (sep_defer != std::string::npos && (sep_eval == std::string::npos || sep_defer <= sep_eval) && (sep_colon == std::string::npos || sep_defer <= sep_colon) && - (sep_equal == std::string::npos || sep_defer <= sep_equal)) - { - sep = sep_defer; + (sep_equal == std::string::npos || sep_defer <= sep_equal)) { + sep = sep_defer; sep_end = sep_defer + 2; - } - else if (sep_eval != std::string::npos && - (sep_defer == std::string::npos || sep_eval <= sep_defer) && - (sep_colon == std::string::npos || sep_eval <= sep_colon) && - (sep_equal == std::string::npos || sep_eval <= sep_equal)) - { - sep = sep_eval; + } else if (sep_eval != std::string::npos && + (sep_defer == std::string::npos || sep_eval <= sep_defer) && + (sep_colon == std::string::npos || sep_eval <= sep_colon) && + (sep_equal == std::string::npos || sep_eval <= sep_equal)) { + sep = sep_eval; sep_end = sep_eval + 2; - } - else if (sep_colon != std::string::npos && - (sep_defer == std::string::npos || sep_colon <= sep_defer) && - (sep_eval == std::string::npos || sep_colon <= sep_eval) && - (sep_equal == std::string::npos || sep_colon <= sep_equal)) - { - sep = sep_colon; + } else if (sep_colon != std::string::npos && + (sep_defer == std::string::npos || sep_colon <= sep_defer) && + (sep_eval == std::string::npos || sep_colon <= sep_eval) && + (sep_equal == std::string::npos || sep_colon <= sep_equal)) { + sep = sep_colon; sep_end = sep_colon + 1; - } - else if (sep_equal != std::string::npos && - (sep_defer == std::string::npos || sep_equal <= sep_defer) && - (sep_eval == std::string::npos || sep_equal <= sep_eval) && - (sep_colon == std::string::npos || sep_equal <= sep_colon)) - { - sep = sep_equal; + } else if (sep_equal != std::string::npos && + (sep_defer == std::string::npos || sep_equal <= sep_defer) && + (sep_eval == std::string::npos || sep_equal <= sep_eval) && + (sep_colon == std::string::npos || sep_equal <= sep_colon)) { + sep = sep_equal; sep_end = sep_equal + 1; } // If sep is known, all is well. - if (sep != std::string::npos) - { + if (sep != std::string::npos) { // Now the only unknown is whethere there is a modifier. - if (dot != std::string::npos && dot < sep) - { - name = text.substr (0, dot); - modifier = text.substr (dot + 1, sep - dot - 1); - } - else - { - name = text.substr (0, sep); + if (dot != std::string::npos && dot < sep) { + name = text.substr(0, dot); + modifier = text.substr(dot + 1, sep - dot - 1); + } else { + name = text.substr(0, sep); modifier = ""; } - separator = text.substr (sep, sep_end - sep); - value = text.substr (sep_end); + separator = text.substr(sep, sep_end - sep); + value = text.substr(sep_end); // An empty name is an error. - if (name.length ()) - return true; + if (name.length()) return true; } return false; @@ -1670,29 +1434,21 @@ bool Lexer::decomposePair ( //////////////////////////////////////////////////////////////////////////////// // / / / [] -bool Lexer::decomposeSubstitution ( - const std::string& text, - std::string& from, - std::string& to, - std::string& flags) -{ +bool Lexer::decomposeSubstitution(const std::string& text, std::string& from, std::string& to, + std::string& flags) { std::string parsed_from; std::string::size_type cursor = 0; - if (readWord (text, "/", cursor, parsed_from) && - parsed_from.length ()) - { + if (readWord(text, "/", cursor, parsed_from) && parsed_from.length()) { --cursor; std::string parsed_to; - if (readWord (text, "/", cursor, parsed_to)) - { - std::string parsed_flags = text.substr (cursor); - if (parsed_flags.find ('/') == std::string::npos) - { - dequote (parsed_from, "/"); - dequote (parsed_to, "/"); + if (readWord(text, "/", cursor, parsed_to)) { + std::string parsed_flags = text.substr(cursor); + if (parsed_flags.find('/') == std::string::npos) { + dequote(parsed_from, "/"); + dequote(parsed_to, "/"); - from = parsed_from; - to = parsed_to; + from = parsed_from; + to = parsed_to; flags = parsed_flags; return true; } @@ -1704,21 +1460,14 @@ bool Lexer::decomposeSubstitution ( //////////////////////////////////////////////////////////////////////////////// // / / [] -bool Lexer::decomposePattern ( - const std::string& text, - std::string& pattern, - std::string& flags) -{ +bool Lexer::decomposePattern(const std::string& text, std::string& pattern, std::string& flags) { std::string ignored; std::string::size_type cursor = 0; - if (readWord (text, "/", cursor, ignored) && - ignored.length ()) - { - auto parsed_flags = text.substr (cursor); - if (parsed_flags.find ('/') == std::string::npos) - { - flags = parsed_flags; - pattern = text.substr (1, cursor - 2 - flags.length ()); + if (readWord(text, "/", cursor, ignored) && ignored.length()) { + auto parsed_flags = text.substr(cursor); + if (parsed_flags.find('/') == std::string::npos) { + flags = parsed_flags; + pattern = text.substr(1, cursor - 2 - flags.length()); return true; } } diff --git a/src/Lexer.h b/src/Lexer.h index 790502eff..f7cfe219d 100644 --- a/src/Lexer.h +++ b/src/Lexer.h @@ -27,95 +27,108 @@ #ifndef INCLUDED_LEXER #define INCLUDED_LEXER -#include -#include -#include #include +#include +#include +#include // Lexer: A UTF8 lexical analyzer for every construct used on the Taskwarrior // command line, with additional recognized types for disambiguation. -class Lexer -{ -public: +class Lexer { + public: // These are overridable. static std::string dateFormat; static std::string::size_type minimumMatchLength; - static std::map attributes; + static std::map attributes; - enum class Type { uuid, number, hex, - string, - url, pair, set, separator, - tag, - path, - substitution, pattern, - op, - dom, identifier, word, - date, duration }; + enum class Type { + uuid, + number, + hex, + string, + url, + pair, + set, + separator, + tag, + path, + substitution, + pattern, + op, + dom, + identifier, + word, + date, + duration + }; - Lexer (const std::string&); - ~Lexer () = default; - bool token (std::string&, Lexer::Type&); - static std::vector split (const std::string&); - static std::string typeToString (Lexer::Type); + Lexer(const std::string&); + ~Lexer() = default; + bool token(std::string&, Lexer::Type&); + static std::vector split(const std::string&); + static std::string typeToString(Lexer::Type); // Static helpers. - static const std::string typeName (const Lexer::Type&); - static bool isIdentifierStart (int); - static bool isIdentifierNext (int); - static bool isSingleCharOperator (int); - static bool isDoubleCharOperator (int, int, int); - static bool isTripleCharOperator (int, int, int, int); - static bool isBoundary (int, int); - static bool isHardBoundary (int, int); - static bool isPunctuation (int); - static bool isAllDigits (const std::string&); - static bool isDOM (const std::string&); - static void dequote (std::string&, const std::string& quotes = "'\""); - static bool wasQuoted (const std::string&); - static bool readWord (const std::string&, const std::string&, std::string::size_type&, std::string&); - static bool readWord (const std::string&, std::string::size_type&, std::string&); - static bool decomposePair (const std::string&, std::string&, std::string&, std::string&, std::string&); - static bool decomposeSubstitution (const std::string&, std::string&, std::string&, std::string&); - static bool decomposePattern (const std::string&, std::string&, std::string&); - static int hexToInt (int); - static int hexToInt (int, int); - static int hexToInt (int, int, int, int); - static std::string::size_type commonLength (const std::string&, const std::string&); - static std::string::size_type commonLength (const std::string&, std::string::size_type, const std::string&, std::string::size_type); - static std::string commify (const std::string&); - static std::string lowerCase (const std::string&); - static std::string ucFirst (const std::string&); - static std::string trimLeft (const std::string& in, const std::string& t = " "); - static std::string trimRight (const std::string& in, const std::string& t = " "); - static std::string trim (const std::string& in, const std::string& t = " "); + static const std::string typeName(const Lexer::Type&); + static bool isIdentifierStart(int); + static bool isIdentifierNext(int); + static bool isSingleCharOperator(int); + static bool isDoubleCharOperator(int, int, int); + static bool isTripleCharOperator(int, int, int, int); + static bool isBoundary(int, int); + static bool isHardBoundary(int, int); + static bool isPunctuation(int); + static bool isAllDigits(const std::string&); + static bool isDOM(const std::string&); + static void dequote(std::string&, const std::string& quotes = "'\""); + static bool wasQuoted(const std::string&); + static bool readWord(const std::string&, const std::string&, std::string::size_type&, + std::string&); + static bool readWord(const std::string&, std::string::size_type&, std::string&); + static bool decomposePair(const std::string&, std::string&, std::string&, std::string&, + std::string&); + static bool decomposeSubstitution(const std::string&, std::string&, std::string&, std::string&); + static bool decomposePattern(const std::string&, std::string&, std::string&); + static int hexToInt(int); + static int hexToInt(int, int); + static int hexToInt(int, int, int, int); + static std::string::size_type commonLength(const std::string&, const std::string&); + static std::string::size_type commonLength(const std::string&, std::string::size_type, + const std::string&, std::string::size_type); + static std::string commify(const std::string&); + static std::string lowerCase(const std::string&); + static std::string ucFirst(const std::string&); + static std::string trimLeft(const std::string& in, const std::string& t = " "); + static std::string trimRight(const std::string& in, const std::string& t = " "); + static std::string trim(const std::string& in, const std::string& t = " "); // Stream Classifiers. - bool isEOS () const; - bool isString (std::string&, Lexer::Type&, const std::string&); - bool isDate (std::string&, Lexer::Type&); - bool isDuration (std::string&, Lexer::Type&); - bool isUUID (std::string&, Lexer::Type&, bool); - bool isNumber (std::string&, Lexer::Type&); - bool isInteger (std::string&, Lexer::Type&); - bool isHexNumber (std::string&, Lexer::Type&); - bool isSeparator (std::string&, Lexer::Type&); - bool isURL (std::string&, Lexer::Type&); - bool isPair (std::string&, Lexer::Type&); - bool isSet (std::string&, Lexer::Type&); - bool isTag (std::string&, Lexer::Type&); - bool isPath (std::string&, Lexer::Type&); - bool isSubstitution (std::string&, Lexer::Type&); - bool isPattern (std::string&, Lexer::Type&); - bool isOperator (std::string&, Lexer::Type&); - bool isDOM (std::string&, Lexer::Type&); - bool isIdentifier (std::string&, Lexer::Type&); - bool isWord (std::string&, Lexer::Type&); - bool isLiteral (const std::string&, bool, bool); - bool isOneOf (const std::vector &, bool, bool); - bool isOneOf (const std::map &, bool, bool); + bool isEOS() const; + bool isString(std::string&, Lexer::Type&, const std::string&); + bool isDate(std::string&, Lexer::Type&); + bool isDuration(std::string&, Lexer::Type&); + bool isUUID(std::string&, Lexer::Type&, bool); + bool isNumber(std::string&, Lexer::Type&); + bool isInteger(std::string&, Lexer::Type&); + bool isHexNumber(std::string&, Lexer::Type&); + bool isSeparator(std::string&, Lexer::Type&); + bool isURL(std::string&, Lexer::Type&); + bool isPair(std::string&, Lexer::Type&); + bool isSet(std::string&, Lexer::Type&); + bool isTag(std::string&, Lexer::Type&); + bool isPath(std::string&, Lexer::Type&); + bool isSubstitution(std::string&, Lexer::Type&); + bool isPattern(std::string&, Lexer::Type&); + bool isOperator(std::string&, Lexer::Type&); + bool isDOM(std::string&, Lexer::Type&); + bool isIdentifier(std::string&, Lexer::Type&); + bool isWord(std::string&, Lexer::Type&); + bool isLiteral(const std::string&, bool, bool); + bool isOneOf(const std::vector&, bool, bool); + bool isOneOf(const std::map&, bool, bool); -private: + private: std::string _text; std::size_t _cursor; std::size_t _eos; diff --git a/src/TDB2.cpp b/src/TDB2.cpp index 185f86e29..d175a61ff 100644 --- a/src/TDB2.cpp +++ b/src/TDB2.cpp @@ -27,64 +27,63 @@ #include // cmake.h include header must come first -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include +#include #include +#include #include -#include #include #include +#include +#include +#include #include + +#include +#include +#include +#include +#include +#include + #include "tc/Server.h" #include "tc/util.h" bool TDB2::debug_mode = false; -static void dependency_scan (std::vector &); +static void dependency_scan(std::vector&); //////////////////////////////////////////////////////////////////////////////// -TDB2::TDB2 () -: replica {tc::Replica()} // in-memory Replica -, _working_set {} -{ -} +TDB2::TDB2() + : replica{tc::Replica()} // in-memory Replica + , + _working_set{} {} //////////////////////////////////////////////////////////////////////////////// -void TDB2::open_replica (const std::string& location, bool create_if_missing) -{ +void TDB2::open_replica(const std::string& location, bool create_if_missing) { replica = tc::Replica(location, create_if_missing); } //////////////////////////////////////////////////////////////////////////////// // Add the new task to the replica. -void TDB2::add (Task& task) -{ +void TDB2::add(Task& task) { // Ensure the task is consistent, and provide defaults if necessary. // bool argument to validate() is "applyDefault", to apply default values for // properties not otherwise given. - task.validate (true); + task.validate(true); - std::string uuid = task.get ("uuid"); + std::string uuid = task.get("uuid"); changes[uuid] = task; // run hooks for this new task - Context::getContext ().hooks.onAdd (task); + Context::getContext().hooks.onAdd(task); - auto innertask = replica.import_task_with_uuid (uuid); + auto innertask = replica.import_task_with_uuid(uuid); { auto guard = replica.mutate_task(innertask); // add the task attributes - for (auto& attr : task.all ()) { + for (auto& attr : task.all()) { // TaskChampion does not store uuid or id in the taskmap if (attr == "uuid" || attr == "id") { continue; @@ -93,35 +92,34 @@ void TDB2::add (Task& task) // Use `set_status` for the task status, to get expected behavior // with respect to the working set. else if (attr == "status") { - innertask.set_status (Task::status2tc (Task::textToStatus (task.get (attr)))); + innertask.set_status(Task::status2tc(Task::textToStatus(task.get(attr)))); } // use `set_modified` to set the modified timestamp, avoiding automatic // updates to this field by TaskChampion. else if (attr == "modified") { - auto mod = (time_t) std::stoi (task.get (attr)); - innertask.set_modified (mod); + auto mod = (time_t)std::stoi(task.get(attr)); + innertask.set_modified(mod); } // otherwise, just set the k/v map value else { - innertask.set_value (attr, std::make_optional (task.get (attr))); + innertask.set_value(attr, std::make_optional(task.get(attr))); } } } - auto ws = replica.working_set (); + auto ws = replica.working_set(); // get the ID that was assigned to this task - auto id = ws.by_uuid (uuid); + auto id = ws.by_uuid(uuid); // update the cached working set with the new information - _working_set = std::make_optional (std::move (ws)); + _working_set = std::make_optional(std::move(ws)); - if (id.has_value ()) { - task.id = id.value(); + if (id.has_value()) { + task.id = id.value(); } - } //////////////////////////////////////////////////////////////////////////////// @@ -139,31 +137,30 @@ void TDB2::add (Task& task) // this method. In this case, this method throws an error that will make sense // to the user. This is especially unlikely since tasks are only deleted when // they have been unmodified for a long time. -void TDB2::modify (Task& task) -{ +void TDB2::modify(Task& task) { // All locally modified tasks are timestamped, implicitly overwriting any // changes the user or hooks tried to apply to the "modified" attribute. - task.setAsNow ("modified"); - task.validate (false); - auto uuid = task.get ("uuid"); + task.setAsNow("modified"); + task.validate(false); + auto uuid = task.get("uuid"); changes[uuid] = task; - // invoke the hook and allow it to modify the task before updating + // invoke the hook and allow it to modify the task before updating Task original; - get (uuid, original); - Context::getContext ().hooks.onModify (original, task); + get(uuid, original); + Context::getContext().hooks.onModify(original, task); - auto maybe_tctask = replica.get_task (uuid); - if (!maybe_tctask.has_value ()) { - throw std::string ("task no longer exists"); + auto maybe_tctask = replica.get_task(uuid); + if (!maybe_tctask.has_value()) { + throw std::string("task no longer exists"); } - auto tctask = std::move (maybe_tctask.value ()); + auto tctask = std::move(maybe_tctask.value()); auto guard = replica.mutate_task(tctask); - auto tctask_map = tctask.get_taskmap (); + auto tctask_map = tctask.get_taskmap(); std::unordered_set seen; - for (auto k : task.all ()) { + for (auto k : task.all()) { // ignore task keys that aren't stored if (k == "uuid") { continue; @@ -183,38 +180,35 @@ void TDB2::modify (Task& task) if (v_new == "") { tctask.set_value(k, {}); } else { - tctask.set_value(k, make_optional (v_new)); + tctask.set_value(k, make_optional(v_new)); } } } // we've now added and updated properties; but must find any deleted properties for (auto kv : tctask_map) { - if (seen.find (kv.first) == seen.end ()) { - tctask.set_value (kv.first, {}); + if (seen.find(kv.first) == seen.end()) { + tctask.set_value(kv.first, {}); } } } //////////////////////////////////////////////////////////////////////////////// -void TDB2::purge (Task& task) -{ - auto uuid = task.get ("uuid"); - replica.delete_task (uuid); +void TDB2::purge(Task& task) { + auto uuid = task.get("uuid"); + replica.delete_task(uuid); } //////////////////////////////////////////////////////////////////////////////// -const tc::WorkingSet &TDB2::working_set () -{ - if (!_working_set.has_value ()) { - _working_set = std::make_optional (replica.working_set ()); +const tc::WorkingSet& TDB2::working_set() { + if (!_working_set.has_value()) { + _working_set = std::make_optional(replica.working_set()); } - return _working_set.value (); + return _working_set.value(); } //////////////////////////////////////////////////////////////////////////////// -void TDB2::get_changes (std::vector & changes) -{ +void TDB2::get_changes(std::vector& changes) { std::map& changes_map = this->changes; changes.clear(); std::transform(changes_map.begin(), changes_map.end(), std::back_inserter(changes), @@ -222,8 +216,7 @@ void TDB2::get_changes (std::vector & changes) } //////////////////////////////////////////////////////////////////////////////// -void TDB2::revert () -{ +void TDB2::revert() { auto undo_ops = replica.get_undo_ops(); if (undo_ops.len == 0) { std::cout << "No operations to undo."; @@ -235,19 +228,18 @@ void TDB2::revert () } else { replica.free_replica_ops(undo_ops); } - replica.rebuild_working_set (false); + replica.rebuild_working_set(false); } //////////////////////////////////////////////////////////////////////////////// -bool TDB2::confirm_revert (struct tc::ffi::TCReplicaOpList undo_ops) -{ +bool TDB2::confirm_revert(struct tc::ffi::TCReplicaOpList undo_ops) { // TODO Use show_diff rather than this basic listing of operations, though // this might be a worthy undo.style itself. std::cout << "The following " << undo_ops.len << " operations would be reverted:\n"; for (size_t i = 0; i < undo_ops.len; i++) { std::cout << "- "; tc::ffi::TCReplicaOp op = undo_ops.items[i]; - switch(op.operation_type) { + switch (op.operation_type) { case tc::ffi::TCReplicaOpType::Create: std::cout << "Create " << replica.get_op_uuid(op); break; @@ -256,114 +248,100 @@ bool TDB2::confirm_revert (struct tc::ffi::TCReplicaOpList undo_ops) break; case tc::ffi::TCReplicaOpType::Update: std::cout << "Update " << replica.get_op_uuid(op) << "\n"; - std::cout << " " << replica.get_op_property(op) << ": " << option_string(replica.get_op_old_value(op)) << " -> " << option_string(replica.get_op_value(op)); + std::cout << " " << replica.get_op_property(op) << ": " + << option_string(replica.get_op_old_value(op)) << " -> " + << option_string(replica.get_op_value(op)); break; case tc::ffi::TCReplicaOpType::UndoPoint: - throw std::string ("Can't undo UndoPoint."); + throw std::string("Can't undo UndoPoint."); break; default: - throw std::string ("Can't undo non-operation."); + throw std::string("Can't undo non-operation."); break; } std::cout << "\n"; } - return ! Context::getContext ().config.getBoolean ("confirmation") || - confirm ("The undo command is not reversible. Are you sure you want to revert to the previous state?"); + return !Context::getContext().config.getBoolean("confirmation") || + confirm( + "The undo command is not reversible. Are you sure you want to revert to the previous " + "state?"); } //////////////////////////////////////////////////////////////////////////////// -std::string TDB2::option_string(std::string input) { - return input == "" ? "" : input; -} +std::string TDB2::option_string(std::string input) { return input == "" ? "" : input; } //////////////////////////////////////////////////////////////////////////////// -void TDB2::show_diff ( - const std::string& current, - const std::string& prior, - const std::string& when) -{ - Datetime lastChange (strtoll (when.c_str (), nullptr, 10)); +void TDB2::show_diff(const std::string& current, const std::string& prior, + const std::string& when) { + Datetime lastChange(strtoll(when.c_str(), nullptr, 10)); // Set the colors. - Color color_red (Context::getContext ().color () ? Context::getContext ().config.get ("color.undo.before") : ""); - Color color_green (Context::getContext ().color () ? Context::getContext ().config.get ("color.undo.after") : ""); + Color color_red( + Context::getContext().color() ? Context::getContext().config.get("color.undo.before") : ""); + Color color_green( + Context::getContext().color() ? Context::getContext().config.get("color.undo.after") : ""); auto before = prior == "" ? Task() : Task(prior); auto after = Task(current); - if (Context::getContext ().config.get ("undo.style") == "side") - { + if (Context::getContext().config.get("undo.style") == "side") { Table view = before.diffForUndoSide(after); std::cout << '\n' - << format ("The last modification was made {1}", lastChange.toString ()) + << format("The last modification was made {1}", lastChange.toString()) << '\n' << '\n' - << '\n' - << view.render () - << '\n'; + << view.render() << '\n'; } - else if (Context::getContext ().config.get ("undo.style") == "diff") - { + else if (Context::getContext().config.get("undo.style") == "diff") { Table view = before.diffForUndoPatch(after, lastChange); - std::cout << '\n' - << view.render () - << '\n'; + std::cout << '\n' << view.render() << '\n'; } } //////////////////////////////////////////////////////////////////////////////// -void TDB2::gc () -{ +void TDB2::gc() { Timer timer; // Allowed as an override, but not recommended. - if (Context::getContext ().config.getBoolean ("gc")) - { - replica.rebuild_working_set (true); + if (Context::getContext().config.getBoolean("gc")) { + replica.rebuild_working_set(true); } - Context::getContext ().time_gc_us += timer.total_us (); + Context::getContext().time_gc_us += timer.total_us(); } //////////////////////////////////////////////////////////////////////////////// -void TDB2::expire_tasks () -{ - replica.expire_tasks (); -} +void TDB2::expire_tasks() { replica.expire_tasks(); } //////////////////////////////////////////////////////////////////////////////// // Latest ID is that of the last pending task. -int TDB2::latest_id () -{ - const tc::WorkingSet &ws = working_set (); - return (int)ws.largest_index (); +int TDB2::latest_id() { + const tc::WorkingSet& ws = working_set(); + return (int)ws.largest_index(); } //////////////////////////////////////////////////////////////////////////////// -const std::vector TDB2::all_tasks () -{ +const std::vector TDB2::all_tasks() { auto all_tctasks = replica.all_tasks(); - std::vector all; - for (auto& tctask : all_tctasks) - all.push_back (Task (std::move (tctask))); + std::vector all; + for (auto& tctask : all_tctasks) all.push_back(Task(std::move(tctask))); return all; } //////////////////////////////////////////////////////////////////////////////// -const std::vector TDB2::pending_tasks () -{ - const tc::WorkingSet &ws = working_set (); - auto largest_index = ws.largest_index (); +const std::vector TDB2::pending_tasks() { + const tc::WorkingSet& ws = working_set(); + auto largest_index = ws.largest_index(); - std::vector result; + std::vector result; for (size_t i = 0; i <= largest_index; i++) { - auto maybe_uuid = ws.by_index (i); - if (maybe_uuid.has_value ()) { - auto maybe_task = replica.get_task (maybe_uuid.value ()); - if (maybe_task.has_value ()) { - result.push_back (Task (std::move (maybe_task.value ()))); + auto maybe_uuid = ws.by_index(i); + if (maybe_uuid.has_value()) { + auto maybe_task = replica.get_task(maybe_uuid.value()); + if (maybe_task.has_value()) { + result.push_back(Task(std::move(maybe_task.value()))); } } } @@ -374,16 +352,15 @@ const std::vector TDB2::pending_tasks () } //////////////////////////////////////////////////////////////////////////////// -const std::vector TDB2::completed_tasks () -{ +const std::vector TDB2::completed_tasks() { auto all_tctasks = replica.all_tasks(); - const tc::WorkingSet &ws = working_set (); + const tc::WorkingSet& ws = working_set(); - std::vector result; + std::vector result; for (auto& tctask : all_tctasks) { // if this task is _not_ in the working set, return it. - if (!ws.by_uuid (tctask.get_uuid ())) { - result.push_back (Task (std::move (tctask))); + if (!ws.by_uuid(tctask.get_uuid())) { + result.push_back(Task(std::move(tctask))); } } @@ -392,10 +369,9 @@ const std::vector TDB2::completed_tasks () //////////////////////////////////////////////////////////////////////////////// // Locate task by ID, wherever it is. -bool TDB2::get (int id, Task& task) -{ - const tc::WorkingSet &ws = working_set (); - const auto maybe_uuid = ws.by_index (id); +bool TDB2::get(int id, Task& task) { + const tc::WorkingSet& ws = working_set(); + const auto maybe_uuid = ws.by_index(id); if (maybe_uuid) { auto maybe_task = replica.get_task(*maybe_uuid); if (maybe_task) { @@ -409,25 +385,24 @@ bool TDB2::get (int id, Task& task) //////////////////////////////////////////////////////////////////////////////// // Locate task by UUID, including by partial ID, wherever it is. -bool TDB2::get (const std::string& uuid, Task& task) -{ +bool TDB2::get(const std::string& uuid, Task& task) { // try by raw uuid, if the length is right - if (uuid.size () == 36) { + if (uuid.size() == 36) { try { - auto maybe_task = replica.get_task (uuid); + auto maybe_task = replica.get_task(uuid); if (maybe_task) { - task = Task{std::move (*maybe_task)}; + task = Task{std::move(*maybe_task)}; return true; } - } catch (const std::string &err) { + } catch (const std::string& err) { return false; } } // Nothing to do but iterate over all tasks and check whether it's closeEnough - for (auto& tctask : replica.all_tasks ()) { - if (closeEnough (tctask.get_uuid (), uuid, uuid.length ())) { - task = Task{std::move (tctask)}; + for (auto& tctask : replica.all_tasks()) { + if (closeEnough(tctask.get_uuid(), uuid, uuid.length())) { + task = Task{std::move(tctask)}; return true; } } @@ -437,34 +412,25 @@ bool TDB2::get (const std::string& uuid, Task& task) //////////////////////////////////////////////////////////////////////////////// // Locate task by UUID, wherever it is. -bool TDB2::has (const std::string& uuid) -{ +bool TDB2::has(const std::string& uuid) { Task task; return get(uuid, task); } //////////////////////////////////////////////////////////////////////////////// -const std::vector TDB2::siblings (Task& task) -{ - std::vector results; - if (task.has ("parent")) - { - std::string parent = task.get ("parent"); +const std::vector TDB2::siblings(Task& task) { + std::vector results; + if (task.has("parent")) { + std::string parent = task.get("parent"); - for (auto& i : this->pending_tasks()) - { + for (auto& i : this->pending_tasks()) { // Do not include self in results. - if (i.id != task.id) - { + if (i.id != task.id) { // Do not include completed or deleted tasks. - if (i.getStatus () != Task::completed && - i.getStatus () != Task::deleted) - { + if (i.getStatus() != Task::completed && i.getStatus() != Task::deleted) { // If task has the same parent, it is a sibling. - if (i.has ("parent") && - i.get ("parent") == parent) - { - results.push_back (i); + if (i.has("parent") && i.get("parent") == parent) { + results.push_back(i); } } } @@ -475,41 +441,40 @@ const std::vector TDB2::siblings (Task& task) } //////////////////////////////////////////////////////////////////////////////// -const std::vector TDB2::children (Task& parent) -{ +const std::vector TDB2::children(Task& parent) { // scan _pending_ tasks for those with `parent` equal to this task - std::vector results; - std::string this_uuid = parent.get ("uuid"); + std::vector results; + std::string this_uuid = parent.get("uuid"); - const tc::WorkingSet &ws = working_set (); - size_t end_idx = ws.largest_index (); + const tc::WorkingSet& ws = working_set(); + size_t end_idx = ws.largest_index(); for (size_t i = 0; i <= end_idx; i++) { - auto uuid_opt = ws.by_index (i); + auto uuid_opt = ws.by_index(i); if (!uuid_opt) { continue; } - auto uuid = uuid_opt.value (); + auto uuid = uuid_opt.value(); // skip self-references if (uuid == this_uuid) { continue; } - auto task_opt = replica.get_task (uuid_opt.value ()); + auto task_opt = replica.get_task(uuid_opt.value()); if (!task_opt) { continue; } - auto task = std::move (task_opt.value ()); + auto task = std::move(task_opt.value()); - auto parent_uuid_opt = task.get_value ("parent"); + auto parent_uuid_opt = task.get_value("parent"); if (!parent_uuid_opt) { continue; } - auto parent_uuid = parent_uuid_opt.value (); + auto parent_uuid = parent_uuid_opt.value(); if (parent_uuid == this_uuid) { - results.push_back (Task (std::move (task))); + results.push_back(Task(std::move(task))); } } @@ -517,40 +482,30 @@ const std::vector TDB2::children (Task& parent) } //////////////////////////////////////////////////////////////////////////////// -std::string TDB2::uuid (int id) -{ - const tc::WorkingSet &ws = working_set (); - return ws.by_index ((size_t)id).value_or (""); +std::string TDB2::uuid(int id) { + const tc::WorkingSet& ws = working_set(); + return ws.by_index((size_t)id).value_or(""); } //////////////////////////////////////////////////////////////////////////////// -int TDB2::id (const std::string& uuid) -{ - const tc::WorkingSet &ws = working_set (); - return (int)ws.by_uuid (uuid).value_or (0); +int TDB2::id(const std::string& uuid) { + const tc::WorkingSet& ws = working_set(); + return (int)ws.by_uuid(uuid).value_or(0); } //////////////////////////////////////////////////////////////////////////////// -int TDB2::num_local_changes () -{ - return (int)replica.num_local_operations (); -} +int TDB2::num_local_changes() { return (int)replica.num_local_operations(); } //////////////////////////////////////////////////////////////////////////////// -int TDB2::num_reverts_possible () -{ - return (int)replica.num_undo_points (); -} +int TDB2::num_reverts_possible() { return (int)replica.num_undo_points(); } //////////////////////////////////////////////////////////////////////////////// -void TDB2::sync (tc::Server server, bool avoid_snapshots) -{ +void TDB2::sync(tc::Server server, bool avoid_snapshots) { replica.sync(std::move(server), avoid_snapshots); } //////////////////////////////////////////////////////////////////////////////// -void TDB2::dump () -{ +void TDB2::dump() { // TODO } @@ -558,24 +513,16 @@ void TDB2::dump () // For any task that has depenencies, follow the chain of dependencies until the // end. Along the way, update the Task::is_blocked and Task::is_blocking data // cache. -static void dependency_scan (std::vector &tasks) -{ - for (auto& left : tasks) - { - for (auto& dep : left.getDependencyUUIDs ()) - { - for (auto& right : tasks) - { - if (right.get ("uuid") == dep) - { +static void dependency_scan(std::vector& tasks) { + for (auto& left : tasks) { + for (auto& dep : left.getDependencyUUIDs()) { + for (auto& right : tasks) { + if (right.get("uuid") == dep) { // GC hasn't run yet, check both tasks for their current status - Task::status lstatus = left.getStatus (); - Task::status rstatus = right.getStatus (); - if (lstatus != Task::completed && - lstatus != Task::deleted && - rstatus != Task::completed && - rstatus != Task::deleted) - { + Task::status lstatus = left.getStatus(); + Task::status rstatus = right.getStatus(); + if (lstatus != Task::completed && lstatus != Task::deleted && + rstatus != Task::completed && rstatus != Task::deleted) { left.is_blocked = true; right.is_blocking = true; } diff --git a/src/TDB2.h b/src/TDB2.h index 87bfa325d..03c8dca5b 100644 --- a/src/TDB2.h +++ b/src/TDB2.h @@ -27,71 +27,71 @@ #ifndef INCLUDED_TDB2 #define INCLUDED_TDB2 -#include -#include -#include -#include -#include -#include #include #include -#include +#include #include +#include + +#include +#include +#include +#include +#include namespace tc { class Server; } // TDB2 Class represents all the files in the task database. -class TDB2 -{ -public: +class TDB2 { + public: static bool debug_mode; - TDB2 (); + TDB2(); - void open_replica (const std::string&, bool create_if_missing); - void add (Task&); - void modify (Task&); - void purge (Task&); - void get_changes (std::vector &); - void revert (); - void gc (); - void expire_tasks (); - int latest_id (); + void open_replica(const std::string &, bool create_if_missing); + void add(Task &); + void modify(Task &); + void purge(Task &); + void get_changes(std::vector &); + void revert(); + void gc(); + void expire_tasks(); + int latest_id(); // Generalized task accessors. - const std::vector all_tasks (); - const std::vector pending_tasks (); - const std::vector completed_tasks (); - bool get (int, Task&); - bool get (const std::string&, Task&); - bool has (const std::string&); - const std::vector siblings (Task&); - const std::vector children (Task&); + const std::vector all_tasks(); + const std::vector pending_tasks(); + const std::vector completed_tasks(); + bool get(int, Task &); + bool get(const std::string &, Task &); + bool has(const std::string &); + const std::vector siblings(Task &); + const std::vector children(Task &); // ID <--> UUID mapping. - std::string uuid (int); - int id (const std::string&); + std::string uuid(int); + int id(const std::string &); - int num_local_changes (); - int num_reverts_possible (); + int num_local_changes(); + int num_reverts_possible(); - void dump (); + void dump(); - void sync (tc::Server server, bool avoid_snapshots); + void sync(tc::Server server, bool avoid_snapshots); bool confirm_revert(struct tc::ffi::TCReplicaOpList); -private: + private: tc::Replica replica; std::optional _working_set; // UUID -> Task containing all tasks modified in this invocation. std::map changes; - const tc::WorkingSet &working_set (); - static std::string option_string (std::string input); - static void show_diff (const std::string&, const std::string&, const std::string&); + const tc::WorkingSet &working_set(); + static std::string option_string(std::string input); + static void show_diff(const std::string &, const std::string &, const std::string &); }; #endif diff --git a/src/Task.cpp b/src/Task.cpp index d483fdd52..a62533cf7 100644 --- a/src/Task.cpp +++ b/src/Task.cpp @@ -28,66 +28,66 @@ // cmake.h include header must come first #include -#include -#include #include +#include + +#include #include #ifdef PRODUCT_TASKWARRIOR -#include #include +#include #endif -#include -#include #include + +#include +#include #ifdef PRODUCT_TASKWARRIOR #include #include #endif -#include #include +#include #ifdef PRODUCT_TASKWARRIOR #include #endif -#include #include +#include #include #ifdef PRODUCT_TASKWARRIOR +#include +#include +#include #include -#include -#include -#include - - -#define APPROACHING_INFINITY 1000 // Close enough. This isn't rocket surgery. +#define APPROACHING_INFINITY 1000 // Close enough. This isn't rocket surgery. static const float epsilon = 0.000001; #endif -std::string Task::defaultProject = ""; -std::string Task::defaultDue = ""; +std::string Task::defaultProject = ""; +std::string Task::defaultDue = ""; std::string Task::defaultScheduled = ""; -bool Task::searchCaseSensitive = true; -bool Task::regex = false; -std::map Task::attributes; +bool Task::searchCaseSensitive = true; +bool Task::regex = false; +std::map Task::attributes; -std::map Task::coefficients; -float Task::urgencyProjectCoefficient = 0.0; -float Task::urgencyActiveCoefficient = 0.0; -float Task::urgencyScheduledCoefficient = 0.0; -float Task::urgencyWaitingCoefficient = 0.0; -float Task::urgencyBlockedCoefficient = 0.0; +std::map Task::coefficients; +float Task::urgencyProjectCoefficient = 0.0; +float Task::urgencyActiveCoefficient = 0.0; +float Task::urgencyScheduledCoefficient = 0.0; +float Task::urgencyWaitingCoefficient = 0.0; +float Task::urgencyBlockedCoefficient = 0.0; float Task::urgencyAnnotationsCoefficient = 0.0; -float Task::urgencyTagsCoefficient = 0.0; -float Task::urgencyDueCoefficient = 0.0; -float Task::urgencyBlockingCoefficient = 0.0; -float Task::urgencyAgeCoefficient = 0.0; -float Task::urgencyAgeMax = 0.0; +float Task::urgencyTagsCoefficient = 0.0; +float Task::urgencyDueCoefficient = 0.0; +float Task::urgencyBlockingCoefficient = 0.0; +float Task::urgencyAgeCoefficient = 0.0; +float Task::urgencyAgeMax = 0.0; -std::map > Task::customOrder; +std::map> Task::customOrder; -static const std::string dummy (""); +static const std::string dummy(""); //////////////////////////////////////////////////////////////////////////////// // The uuid and id attributes must be exempt from comparison. @@ -101,86 +101,84 @@ static const std::string dummy (""); // These two conditions are necessary. They are also sufficient, since there // can be no extra data attribute in the second set, due to the same attribute // set sizes. -bool Task::operator== (const Task& other) -{ - if (data.size () != other.data.size ()) - return false; +bool Task::operator==(const Task& other) { + if (data.size() != other.data.size()) return false; for (const auto& i : data) - if (i.first != "uuid" && - i.second != other.get (i.first)) - return false; + if (i.first != "uuid" && i.second != other.get(i.first)) return false; return true; } //////////////////////////////////////////////////////////////////////////////// -bool Task::operator!= (const Task& other) -{ - return !(*this == other); -} +bool Task::operator!=(const Task& other) { return !(*this == other); } //////////////////////////////////////////////////////////////////////////////// -Task::Task (const std::string& input) -{ - id = 0; - urgency_value = 0.0; - recalc_urgency = true; - is_blocked = false; - is_blocking = false; +Task::Task(const std::string& input) { + id = 0; + urgency_value = 0.0; + recalc_urgency = true; + is_blocked = false; + is_blocking = false; annotation_count = 0; - parse (input); + parse(input); } //////////////////////////////////////////////////////////////////////////////// -Task::Task (const json::object* obj) -{ - id = 0; - urgency_value = 0.0; - recalc_urgency = true; - is_blocked = false; - is_blocking = false; +Task::Task(const json::object* obj) { + id = 0; + urgency_value = 0.0; + recalc_urgency = true; + is_blocked = false; + is_blocking = false; annotation_count = 0; - parseJSON (obj); + parseJSON(obj); } //////////////////////////////////////////////////////////////////////////////// -Task::Task (tc::Task obj) -{ - id = 0; - urgency_value = 0.0; - recalc_urgency = true; - is_blocked = false; - is_blocking = false; +Task::Task(tc::Task obj) { + id = 0; + urgency_value = 0.0; + recalc_urgency = true; + is_blocked = false; + is_blocking = false; annotation_count = 0; - parseTC (obj); + parseTC(obj); } //////////////////////////////////////////////////////////////////////////////// -Task::status Task::textToStatus (const std::string& input) -{ - if (input[0] == 'p') return Task::pending; - else if (input[0] == 'c') return Task::completed; - else if (input[0] == 'd') return Task::deleted; - else if (input[0] == 'r') return Task::recurring; +Task::status Task::textToStatus(const std::string& input) { + if (input[0] == 'p') + return Task::pending; + else if (input[0] == 'c') + return Task::completed; + else if (input[0] == 'd') + return Task::deleted; + else if (input[0] == 'r') + return Task::recurring; // for compatibility, parse `w` as pending; Task::getStatus will // apply the virtual waiting status if appropriate - else if (input[0] == 'w') return Task::pending; + else if (input[0] == 'w') + return Task::pending; - throw format ("The status '{1}' is not valid.", input); + throw format("The status '{1}' is not valid.", input); } //////////////////////////////////////////////////////////////////////////////// -std::string Task::statusToText (Task::status s) -{ - if (s == Task::pending) return "pending"; - else if (s == Task::recurring) return "recurring"; - else if (s == Task::waiting) return "waiting"; - else if (s == Task::completed) return "completed"; - else if (s == Task::deleted) return "deleted"; +std::string Task::statusToText(Task::status s) { + if (s == Task::pending) + return "pending"; + else if (s == Task::recurring) + return "recurring"; + else if (s == Task::waiting) + return "waiting"; + else if (s == Task::completed) + return "completed"; + else if (s == Task::deleted) + return "deleted"; return "pending"; } @@ -188,161 +186,133 @@ std::string Task::statusToText (Task::status s) //////////////////////////////////////////////////////////////////////////////// // Returns a proper handle to the task. Tasks should not be referenced by UUIDs // as long as they have non-zero ID. -const std::string Task::identifier (bool shortened /* = false */) const -{ +const std::string Task::identifier(bool shortened /* = false */) const { if (id != 0) - return format (id); + return format(id); else if (shortened) - return get ("uuid").substr (0, 8); + return get("uuid").substr(0, 8); else - return get ("uuid"); + return get("uuid"); } //////////////////////////////////////////////////////////////////////////////// -void Task::setAsNow (const std::string& att) -{ +void Task::setAsNow(const std::string& att) { char now[22]; - snprintf (now, 22, "%lli", (long long int) time (nullptr)); - set (att, now); + snprintf(now, 22, "%lli", (long long int)time(nullptr)); + set(att, now); recalc_urgency = true; } //////////////////////////////////////////////////////////////////////////////// -bool Task::has (const std::string& name) const -{ - if (data.find (name) != data.end ()) - return true; +bool Task::has(const std::string& name) const { + if (data.find(name) != data.end()) return true; return false; } //////////////////////////////////////////////////////////////////////////////// -std::vector Task::all () const -{ - std::vector all; - for (const auto& i : data) - all.push_back (i.first); +std::vector Task::all() const { + std::vector all; + for (const auto& i : data) all.push_back(i.first); return all; } //////////////////////////////////////////////////////////////////////////////// -const std::string Task::get (const std::string& name) const -{ - auto i = data.find (name); - if (i != data.end ()) - return i->second; +const std::string Task::get(const std::string& name) const { + auto i = data.find(name); + if (i != data.end()) return i->second; return ""; } //////////////////////////////////////////////////////////////////////////////// -const std::string& Task::get_ref (const std::string& name) const -{ - auto i = data.find (name); - if (i != data.end ()) - return i->second; +const std::string& Task::get_ref(const std::string& name) const { + auto i = data.find(name); + if (i != data.end()) return i->second; return dummy; } //////////////////////////////////////////////////////////////////////////////// -int Task::get_int (const std::string& name) const -{ - auto i = data.find (name); - if (i != data.end ()) - return strtol (i->second.c_str (), nullptr, 10); +int Task::get_int(const std::string& name) const { + auto i = data.find(name); + if (i != data.end()) return strtol(i->second.c_str(), nullptr, 10); return 0; } //////////////////////////////////////////////////////////////////////////////// -unsigned long Task::get_ulong (const std::string& name) const -{ - auto i = data.find (name); - if (i != data.end ()) - return strtoul (i->second.c_str (), nullptr, 10); +unsigned long Task::get_ulong(const std::string& name) const { + auto i = data.find(name); + if (i != data.end()) return strtoul(i->second.c_str(), nullptr, 10); return 0; } //////////////////////////////////////////////////////////////////////////////// -float Task::get_float (const std::string& name) const -{ - auto i = data.find (name); - if (i != data.end ()) - return strtof (i->second.c_str (), nullptr); +float Task::get_float(const std::string& name) const { + auto i = data.find(name); + if (i != data.end()) return strtof(i->second.c_str(), nullptr); return 0.0; } //////////////////////////////////////////////////////////////////////////////// -time_t Task::get_date (const std::string& name) const -{ - auto i = data.find (name); - if (i != data.end ()) - return (time_t) strtoul (i->second.c_str (), nullptr, 10); +time_t Task::get_date(const std::string& name) const { + auto i = data.find(name); + if (i != data.end()) return (time_t)strtoul(i->second.c_str(), nullptr, 10); return 0; } //////////////////////////////////////////////////////////////////////////////// -void Task::set (const std::string& name, const std::string& value) -{ +void Task::set(const std::string& name, const std::string& value) { data[name] = value; - if (isAnnotationAttr (name)) - ++annotation_count; + if (isAnnotationAttr(name)) ++annotation_count; recalc_urgency = true; } //////////////////////////////////////////////////////////////////////////////// -void Task::set (const std::string& name, long long value) -{ - data[name] = format (value); +void Task::set(const std::string& name, long long value) { + data[name] = format(value); recalc_urgency = true; } //////////////////////////////////////////////////////////////////////////////// -void Task::remove (const std::string& name) -{ - if (data.erase (name)) - recalc_urgency = true; +void Task::remove(const std::string& name) { + if (data.erase(name)) recalc_urgency = true; - if (isAnnotationAttr (name)) - --annotation_count; + if (isAnnotationAttr(name)) --annotation_count; } //////////////////////////////////////////////////////////////////////////////// -Task::status Task::getStatus () const -{ - if (! has ("status")) - return Task::pending; +Task::status Task::getStatus() const { + if (!has("status")) return Task::pending; - auto status = textToStatus (get ("status")); + auto status = textToStatus(get("status")); // Implement the "virtual" Task::waiting status, which is not stored on-disk // but is defined as a pending task with a `wait` attribute in the future. // This is workaround for 2.6.0, remove in 3.0.0. - if (status == Task::pending && is_waiting ()) { - return Task::waiting; + if (status == Task::pending && is_waiting()) { + return Task::waiting; } return status; } //////////////////////////////////////////////////////////////////////////////// -void Task::setStatus (Task::status status) -{ +void Task::setStatus(Task::status status) { // the 'waiting' status is a virtual version of 'pending', so translate // that back to 'pending' here - if (status == Task::waiting) - status = Task::pending; + if (status == Task::waiting) status = Task::pending; - set ("status", statusToText (status)); + set("status", statusToText(status)); recalc_urgency = true; } @@ -350,33 +320,27 @@ void Task::setStatus (Task::status status) #ifdef PRODUCT_TASKWARRIOR //////////////////////////////////////////////////////////////////////////////// // Determines status of a date attribute. -Task::dateState Task::getDateState (const std::string& name) const -{ - std::string value = get (name); - if (value.length ()) - { - Datetime reference (value); +Task::dateState Task::getDateState(const std::string& name) const { + std::string value = get(name); + if (value.length()) { + Datetime reference(value); Datetime now; - Datetime today ("today"); + Datetime today("today"); - if (reference < today) - return dateBeforeToday; + if (reference < today) return dateBeforeToday; - if (reference.sameDay (now)) - { + if (reference.sameDay(now)) { if (reference < now) return dateEarlierToday; else return dateLaterToday; } - int imminentperiod = Context::getContext ().config.getInteger ("due"); - if (imminentperiod == 0) - return dateAfterToday; + int imminentperiod = Context::getContext().config.getInteger("due"); + if (imminentperiod == 0) return dateAfterToday; Datetime imminentDay = today + imminentperiod * 86400; - if (reference < imminentDay) - return dateAfterToday; + if (reference < imminentDay) return dateAfterToday; } return dateNotDue; @@ -385,36 +349,24 @@ Task::dateState Task::getDateState (const std::string& name) const //////////////////////////////////////////////////////////////////////////////// // An empty task is typically a "dummy", such as in DOM evaluation, which may or // may not occur in the context of a task. -bool Task::is_empty () const -{ - return data.size () == 0; -} +bool Task::is_empty() const { return data.size() == 0; } //////////////////////////////////////////////////////////////////////////////// // Ready means pending, not blocked and either not scheduled or scheduled before // now. -bool Task::is_ready () const -{ - return getStatus () == Task::pending && - ! is_blocked && - (! has ("scheduled") || - Datetime ("now").operator> (get_date ("scheduled"))); +bool Task::is_ready() const { + return getStatus() == Task::pending && !is_blocked && + (!has("scheduled") || Datetime("now").operator>(get_date("scheduled"))); } //////////////////////////////////////////////////////////////////////////////// -bool Task::is_due () const -{ - if (has ("due")) - { - Task::status status = getStatus (); +bool Task::is_due() const { + if (has("due")) { + Task::status status = getStatus(); - if (status != Task::completed && - status != Task::deleted) - { - Task::dateState state = getDateState ("due"); - if (state == dateAfterToday || - state == dateEarlierToday || - state == dateLaterToday) + if (status != Task::completed && status != Task::deleted) { + Task::dateState state = getDateState("due"); + if (state == dateAfterToday || state == dateEarlierToday || state == dateLaterToday) return true; } } @@ -423,17 +375,12 @@ bool Task::is_due () const } //////////////////////////////////////////////////////////////////////////////// -bool Task::is_dueyesterday () const -{ - if (has ("due")) - { - Task::status status = getStatus (); +bool Task::is_dueyesterday() const { + if (has("due")) { + Task::status status = getStatus(); - if (status != Task::completed && - status != Task::deleted) - { - if (Datetime ("yesterday").sameDay (get_date ("due"))) - return true; + if (status != Task::completed && status != Task::deleted) { + if (Datetime("yesterday").sameDay(get_date("due"))) return true; } } @@ -441,19 +388,13 @@ bool Task::is_dueyesterday () const } //////////////////////////////////////////////////////////////////////////////// -bool Task::is_duetoday () const -{ - if (has ("due")) - { - Task::status status = getStatus (); +bool Task::is_duetoday() const { + if (has("due")) { + Task::status status = getStatus(); - if (status != Task::completed && - status != Task::deleted) - { - Task::dateState state = getDateState ("due"); - if (state == dateEarlierToday || - state == dateLaterToday) - return true; + if (status != Task::completed && status != Task::deleted) { + Task::dateState state = getDateState("due"); + if (state == dateEarlierToday || state == dateLaterToday) return true; } } @@ -461,17 +402,12 @@ bool Task::is_duetoday () const } //////////////////////////////////////////////////////////////////////////////// -bool Task::is_duetomorrow () const -{ - if (has ("due")) - { - Task::status status = getStatus (); +bool Task::is_duetomorrow() const { + if (has("due")) { + Task::status status = getStatus(); - if (status != Task::completed && - status != Task::deleted) - { - if (Datetime ("tomorrow").sameDay (get_date ("due"))) - return true; + if (status != Task::completed && status != Task::deleted) { + if (Datetime("tomorrow").sameDay(get_date("due"))) return true; } } @@ -479,19 +415,13 @@ bool Task::is_duetomorrow () const } //////////////////////////////////////////////////////////////////////////////// -bool Task::is_dueweek () const -{ - if (has ("due")) - { - Task::status status = getStatus (); +bool Task::is_dueweek() const { + if (has("due")) { + Task::status status = getStatus(); - if (status != Task::completed && - status != Task::deleted) - { - Datetime due (get_date ("due")); - if (due >= Datetime ("sow") && - due <= Datetime ("eow")) - return true; + if (status != Task::completed && status != Task::deleted) { + Datetime due(get_date("due")); + if (due >= Datetime("sow") && due <= Datetime("eow")) return true; } } @@ -499,19 +429,13 @@ bool Task::is_dueweek () const } //////////////////////////////////////////////////////////////////////////////// -bool Task::is_duemonth () const -{ - if (has ("due")) - { - Task::status status = getStatus (); +bool Task::is_duemonth() const { + if (has("due")) { + Task::status status = getStatus(); - if (status != Task::completed && - status != Task::deleted) - { - Datetime due (get_date ("due")); - if (due >= Datetime ("som") && - due <= Datetime ("eom")) - return true; + if (status != Task::completed && status != Task::deleted) { + Datetime due(get_date("due")); + if (due >= Datetime("som") && due <= Datetime("eom")) return true; } } @@ -519,19 +443,13 @@ bool Task::is_duemonth () const } //////////////////////////////////////////////////////////////////////////////// -bool Task::is_duequarter () const -{ - if (has ("due")) - { - Task::status status = getStatus (); +bool Task::is_duequarter() const { + if (has("due")) { + Task::status status = getStatus(); - if (status != Task::completed && - status != Task::deleted) - { - Datetime due (get_date ("due")); - if (due >= Datetime ("soq") && - due <= Datetime ("eoq")) - return true; + if (status != Task::completed && status != Task::deleted) { + Datetime due(get_date("due")); + if (due >= Datetime("soq") && due <= Datetime("eoq")) return true; } } @@ -539,19 +457,13 @@ bool Task::is_duequarter () const } //////////////////////////////////////////////////////////////////////////////// -bool Task::is_dueyear () const -{ - if (has ("due")) - { - Task::status status = getStatus (); +bool Task::is_dueyear() const { + if (has("due")) { + Task::status status = getStatus(); - if (status != Task::completed && - status != Task::deleted) - { - Datetime due (get_date ("due")); - if (due >= Datetime ("soy") && - due <= Datetime ("eoy")) - return true; + if (status != Task::completed && status != Task::deleted) { + Datetime due(get_date("due")); + if (due >= Datetime("soy") && due <= Datetime("eoy")) return true; } } @@ -559,44 +471,31 @@ bool Task::is_dueyear () const } //////////////////////////////////////////////////////////////////////////////// -bool Task::is_udaPresent () const -{ - for (auto& col : Context::getContext ().columns) - if (col.second->is_uda () && - has (col.first)) - return true; +bool Task::is_udaPresent() const { + for (auto& col : Context::getContext().columns) + if (col.second->is_uda() && has(col.first)) return true; return false; } //////////////////////////////////////////////////////////////////////////////// -bool Task::is_orphanPresent () const -{ +bool Task::is_orphanPresent() const { for (auto& att : data) - if (! isAnnotationAttr (att.first) && - ! isTagAttr (att.first) && - ! isDepAttr (att.first) && - Context::getContext ().columns.find (att.first) == Context::getContext ().columns.end ()) + if (!isAnnotationAttr(att.first) && !isTagAttr(att.first) && !isDepAttr(att.first) && + Context::getContext().columns.find(att.first) == Context::getContext().columns.end()) return true; return false; } //////////////////////////////////////////////////////////////////////////////// -bool Task::is_overdue () const -{ - if (has ("due")) - { - Task::status status = getStatus (); +bool Task::is_overdue() const { + if (has("due")) { + Task::status status = getStatus(); - if (status != Task::completed && - status != Task::deleted && - status != Task::recurring) - { - Task::dateState state = getDateState ("due"); - if (state == dateEarlierToday || - state == dateBeforeToday) - return true; + if (status != Task::completed && status != Task::deleted && status != Task::recurring) { + Task::dateState state = getDateState("due"); + if (state == dateEarlierToday || state == dateBeforeToday) return true; } } @@ -610,14 +509,11 @@ bool Task::is_overdue () const // While this is not consistent with other attribute-based virtual tags, such // as +BLOCKED, it is more backwards compatible with how +WAITING virtual tag // behaved in the past, when waiting had a dedicated status value. -bool Task::is_waiting () const -{ - if (has ("wait") && get ("status") == "pending") - { +bool Task::is_waiting() const { + if (has("wait") && get("status") == "pending") { Datetime now; - Datetime wait (get_date ("wait")); - if (wait > now) - return true; + Datetime wait(get_date("wait")); + if (wait > now) return true; } return false; @@ -625,12 +521,11 @@ bool Task::is_waiting () const //////////////////////////////////////////////////////////////////////////////// // Try a JSON parse. -void Task::parse (const std::string& input) -{ - parseJSON (input); +void Task::parse(const std::string& input) { + parseJSON(input); // for compatibility, include all tags in `tags` as `tag_..` attributes - if (data.find ("tags") != data.end ()) { + if (data.find("tags") != data.end()) { for (auto& tag : split(data["tags"], ',')) { data[tag2Attr(tag)] = "x"; } @@ -639,7 +534,7 @@ void Task::parse (const std::string& input) fixTagsAttribute(); // same for `depends` / `dep_..` - if (data.find ("depends") != data.end ()) { + if (data.find("depends") != data.end()) { for (auto& dep : split(data["depends"], ',')) { data[dep2Attr(dep)] = "x"; } @@ -651,27 +546,21 @@ void Task::parse (const std::string& input) //////////////////////////////////////////////////////////////////////////////// // Note that all fields undergo encode/decode. -void Task::parseJSON (const std::string& line) -{ +void Task::parseJSON(const std::string& line) { // Parse the whole thing. - json::value* root = json::parse (line); - if (root && - root->type () == json::j_object) - parseJSON ((json::object*) root); + json::value* root = json::parse(line); + if (root && root->type() == json::j_object) parseJSON((json::object*)root); delete root; } //////////////////////////////////////////////////////////////////////////////// -void Task::parseJSON (const json::object* root_obj) -{ +void Task::parseJSON(const json::object* root_obj) { // For each object element... - for (auto& i : root_obj->_data) - { + for (auto& i : root_obj->_data) { // If the attribute is a recognized column. std::string type = Task::attributes[i.first]; - if (type != "") - { + if (type != "") { // Any specified id is ignored. if (i.first == "id") ; @@ -681,51 +570,44 @@ void Task::parseJSON (const json::object* root_obj) ; // TW-1274 Standardization. - else if (i.first == "modification") - { - auto text = i.second->dump (); - Lexer::dequote (text); - Datetime d (text); - set ("modified", d.toEpochString ()); + else if (i.first == "modification") { + auto text = i.second->dump(); + Lexer::dequote(text); + Datetime d(text); + set("modified", d.toEpochString()); } // Dates are converted from ISO to epoch. - else if (type == "date") - { - auto text = i.second->dump (); - Lexer::dequote (text); - Datetime d (text); - set (i.first, text == "" ? "" : d.toEpochString ()); + else if (type == "date") { + auto text = i.second->dump(); + Lexer::dequote(text); + Datetime d(text); + set(i.first, text == "" ? "" : d.toEpochString()); } // Tags are an array of JSON strings. - else if (i.first == "tags" && i.second->type() == json::j_array) - { + else if (i.first == "tags" && i.second->type() == json::j_array) { auto tags = (json::array*)i.second; - for (auto& t : tags->_data) - { + for (auto& t : tags->_data) { auto tag = (json::string*)t; - addTag (tag->_data); + addTag(tag->_data); } } // Dependencies can be exported as an array of strings. // 2016-02-21: This will be the only option in future releases. // See other 2016-02-21 comments for details. - else if (i.first == "depends" && i.second->type() == json::j_array) - { + else if (i.first == "depends" && i.second->type() == json::j_array) { auto deps = (json::array*)i.second; - for (auto& t : deps->_data) - { + for (auto& t : deps->_data) { auto dep = (json::string*)t; - addDependency (dep->_data); + addDependency(dep->_data); } } // Dependencies can be exported as a single comma-separated string. // 2016-02-21: Deprecated - see other 2016-02-21 comments for details. - else if (i.first == "depends" && i.second->type() == json::j_string) - { + else if (i.first == "depends" && i.second->type() == json::j_string) { auto deps = (json::string*)i.second; // Fix for issue#2689: taskserver sometimes encodes the depends @@ -734,64 +616,57 @@ void Task::parseJSON (const json::object* root_obj) // it invalid JSON. Since we know the characters we're looking for, // we'll just filter out everything else. std::string deps_str = deps->_data; - if (deps_str.front () == '[' && deps_str.back () == ']') { + if (deps_str.front() == '[' && deps_str.back() == ']') { std::string filtered; - for (auto &c: deps_str) { - if ((c >= '0' && c <= '9') || - (c >= 'a' && c <= 'f') || - c == ',' || c == '-') { - filtered.push_back(c); - } - } - deps_str = filtered; + for (auto& c : deps_str) { + if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || c == ',' || c == '-') { + filtered.push_back(c); + } + } + deps_str = filtered; } - auto uuids = split (deps_str, ','); + auto uuids = split(deps_str, ','); - for (const auto& uuid : uuids) - addDependency (uuid); + for (const auto& uuid : uuids) addDependency(uuid); } // Strings are decoded. - else if (type == "string") - { - auto text = i.second->dump (); - Lexer::dequote (text); - set (i.first, json::decode (text)); + else if (type == "string") { + auto text = i.second->dump(); + Lexer::dequote(text); + set(i.first, json::decode(text)); } // Other types are simply added. - else - { - auto text = i.second->dump (); - Lexer::dequote (text); - set (i.first, text); + else { + auto text = i.second->dump(); + Lexer::dequote(text); + set(i.first, text); } } // UDA orphans and annotations do not have columns. - else - { + else { // Annotations are an array of JSON objects with 'entry' and // 'description' values and must be converted. - if (i.first == "annotations") - { - std::map annos; + if (i.first == "annotations") { + std::map annos; // Fail if 'annotations' is not an array if (i.second->type() != json::j_array) { - throw format ("Annotations is malformed: {1}", i.second->dump ()); + throw format("Annotations is malformed: {1}", i.second->dump()); } auto atts = (json::array*)i.second; - for (auto& annotations : atts->_data) - { + for (auto& annotations : atts->_data) { auto annotation = (json::object*)annotations; // Extract description. Fail if not present. auto what = (json::string*)annotation->_data["description"]; - if (! what) { - annotation->_data.erase ("description"); // Erase NULL description inserted by failed lookup above - throw format ("Annotation is missing a description: {1}", annotation->dump ()); + if (!what) { + annotation->_data.erase( + "description"); // Erase NULL description inserted by failed lookup above + throw format("Annotation is missing a description: {1}", annotation->dump()); } // Extract 64-bit annotation entry value @@ -801,10 +676,10 @@ void Task::parseJSON (const json::object* root_obj) // Extract entry. Use current time if not present. auto when = (json::string*)annotation->_data["entry"]; if (when) - ann_timestamp = (long long) (Datetime (when->_data).toEpoch ()); + ann_timestamp = (long long)(Datetime(when->_data).toEpoch()); else { - annotation->_data.erase ("entry"); // Erase NULL entry inserted by failed lookup above - ann_timestamp = (long long) (Datetime ().toEpoch ()); + annotation->_data.erase("entry"); // Erase NULL entry inserted by failed lookup above + ann_timestamp = (long long)(Datetime().toEpoch()); } std::stringstream name; @@ -812,34 +687,29 @@ void Task::parseJSON (const json::object* root_obj) // Increment the entry timestamp in case of a conflict. Same // behaviour as CmdAnnotate. - while (annos.find(name.str ()) != annos.end ()) - { - name.str (""); // Clear - ann_timestamp++; - name << "annotation_" << ann_timestamp; + while (annos.find(name.str()) != annos.end()) { + name.str(""); // Clear + ann_timestamp++; + name << "annotation_" << ann_timestamp; } - annos.emplace (name.str (), json::decode (what->_data)); + annos.emplace(name.str(), json::decode(what->_data)); } - setAnnotations (annos); + setAnnotations(annos); } // UDA Orphan - must be preserved. - else - { + else { #ifdef PRODUCT_TASKWARRIOR std::stringstream message; - message << "Task::parseJSON found orphan '" - << i.first - << "' with value '" - << i.second + message << "Task::parseJSON found orphan '" << i.first << "' with value '" << i.second << "' --> preserved\n"; - Context::getContext ().debug (message.str ()); + Context::getContext().debug(message.str()); #endif - auto text = i.second->dump (); - Lexer::dequote (text); - set (i.first, json::decode (text)); + auto text = i.second->dump(); + Lexer::dequote(text); + set(i.first, json::decode(text)); } } } @@ -847,22 +717,19 @@ void Task::parseJSON (const json::object* root_obj) //////////////////////////////////////////////////////////////////////////////// // Note that all fields undergo encode/decode. -void Task::parseTC (const tc::Task& task) -{ - data = task.get_taskmap (); +void Task::parseTC(const tc::Task& task) { + data = task.get_taskmap(); // count annotations annotation_count = 0; - for (auto i : data) - { - if (isAnnotationAttr (i.first)) - { + for (auto i : data) { + if (isAnnotationAttr(i.first)) { ++annotation_count; } } - data["uuid"] = task.get_uuid (); - id = Context::getContext ().tdb2.id (data["uuid"]); + data["uuid"] = task.get_uuid(); + id = Context::getContext().tdb2.id(data["uuid"]); is_blocking = task.is_blocking(); is_blocked = task.is_blocked(); @@ -870,111 +737,96 @@ void Task::parseTC (const tc::Task& task) //////////////////////////////////////////////////////////////////////////////// // No legacy formats are currently supported as of 2.4.0. -void Task::parseLegacy (const std::string& line) -{ - switch (determineVersion (line)) - { - // File format version 1, from 2006-11-27 - 2007-12-31, v0.x+ - v0.9.3 - case 1: throw std::string ("Taskwarrior no longer supports file format 1, originally used between 27 November 2006 and 31 December 2007."); +void Task::parseLegacy(const std::string& line) { + switch (determineVersion(line)) { + // File format version 1, from 2006-11-27 - 2007-12-31, v0.x+ - v0.9.3 + case 1: + throw std::string( + "Taskwarrior no longer supports file format 1, originally used between 27 November 2006 " + "and 31 December 2007."); - // File format version 2, from 2008-1-1 - 2009-3-23, v0.9.3 - v1.5.0 - case 2: throw std::string ("Taskwarrior no longer supports file format 2, originally used between 1 January 2008 and 12 April 2009."); + // File format version 2, from 2008-1-1 - 2009-3-23, v0.9.3 - v1.5.0 + case 2: + throw std::string( + "Taskwarrior no longer supports file format 2, originally used between 1 January 2008 " + "and 12 April 2009."); - // File format version 3, from 2009-3-23 - 2009-05-16, v1.6.0 - v1.7.1 - case 3: throw std::string ("Taskwarrior no longer supports file format 3, originally used between 23 March 2009 and 16 May 2009."); + // File format version 3, from 2009-3-23 - 2009-05-16, v1.6.0 - v1.7.1 + case 3: + throw std::string( + "Taskwarrior no longer supports file format 3, originally used between 23 March 2009 and " + "16 May 2009."); - // File format version 4, from 2009-05-16 - today, v1.7.1+ - case 4: - break; + // File format version 4, from 2009-05-16 - today, v1.7.1+ + case 4: + break; - default: + default: #ifdef PRODUCT_TASKWARRIOR - std::stringstream message; - message << "Invalid fileformat at line '" - << line - << '\''; - Context::getContext ().debug (message.str ()); + std::stringstream message; + message << "Invalid fileformat at line '" << line << '\''; + Context::getContext().debug(message.str()); #endif - throw std::string ("Unrecognized Taskwarrior file format or blank line in data."); - break; + throw std::string("Unrecognized Taskwarrior file format or blank line in data."); + break; } recalc_urgency = true; } //////////////////////////////////////////////////////////////////////////////// -std::string Task::composeJSON (bool decorate /*= false*/) const -{ +std::string Task::composeJSON(bool decorate /*= false*/) const { std::stringstream out; out << '{'; // ID inclusion is optional, but not a good idea, because it remains correct // only until the next gc. - if (decorate) - out << "\"id\":" << id << ','; + if (decorate) out << "\"id\":" << id << ','; // First the non-annotations. int attributes_written = 0; - for (auto& i : data) - { + for (auto& i : data) { // Annotations are not written out here. - if (! i.first.compare (0, 11, "annotation_", 11)) - continue; + if (!i.first.compare(0, 11, "annotation_", 11)) continue; // Tags and dependencies are handled below - if (i.first == "tags" || isTagAttr (i.first)) - continue; - if (i.first == "depends" || isDepAttr (i.first)) - continue; + if (i.first == "tags" || isTagAttr(i.first)) continue; + if (i.first == "depends" || isDepAttr(i.first)) continue; // If value is an empty string, do not ever output it - if (i.second == "") - continue; + if (i.second == "") continue; - if (attributes_written) - out << ','; + if (attributes_written) out << ','; std::string type = Task::attributes[i.first]; - if (type == "") - type = "string"; + if (type == "") type = "string"; // Date fields are written as ISO 8601. - if (type == "date") - { - Datetime d (i.second); - out << '"' - << (i.first == "modification" ? "modified" : i.first) + if (type == "date") { + Datetime d(i.second); + out << '"' << (i.first == "modification" ? "modified" : i.first) << "\":\"" // Date was deleted, do not export parsed empty string - << (i.second == "" ? "" : d.toISO ()) - << '"'; + << (i.second == "" ? "" : d.toISO()) << '"'; ++attributes_written; } -/* - else if (type == "duration") - { - // TODO Emit Datetime - } -*/ - else if (type == "numeric") - { - out << '"' - << i.first - << "\":" - << i.second; + /* + else if (type == "duration") + { + // TODO Emit Datetime + } + */ + else if (type == "numeric") { + out << '"' << i.first << "\":" << i.second; ++attributes_written; } // Everything else is a quoted value. - else - { - out << '"' - << i.first - << "\":\"" - << (type == "string" ? json::encode (i.second) : i.second) + else { + out << '"' << i.first << "\":\"" << (type == "string" ? json::encode(i.second) : i.second) << '"'; ++attributes_written; @@ -982,24 +834,16 @@ std::string Task::composeJSON (bool decorate /*= false*/) const } // Now the annotations, if any. - if (annotation_count) - { - out << ',' - << "\"annotations\":["; + if (annotation_count) { + out << ',' << "\"annotations\":["; int annotations_written = 0; - for (auto& i : data) - { - if (! i.first.compare (0, 11, "annotation_", 11)) - { - if (annotations_written) - out << ','; + for (auto& i : data) { + if (!i.first.compare(0, 11, "annotation_", 11)) { + if (annotations_written) out << ','; - Datetime d (i.first.substr (11)); - out << R"({"entry":")" - << d.toISO () - << R"(","description":")" - << json::encode (i.second) + Datetime d(i.first.substr(11)); + out << R"({"entry":")" << d.toISO() << R"(","description":")" << json::encode(i.second) << "\"}"; ++annotations_written; @@ -1010,16 +854,12 @@ std::string Task::composeJSON (bool decorate /*= false*/) const } auto tags = getTags(); - if (tags.size() > 0) - { - out << ',' - << "\"tags\":["; + if (tags.size() > 0) { + out << ',' << "\"tags\":["; int count = 0; - for (const auto& tag : tags) - { - if (count++) - out << ','; + for (const auto& tag : tags) { + if (count++) out << ','; out << '"' << tag << '"'; } @@ -1028,17 +868,13 @@ std::string Task::composeJSON (bool decorate /*= false*/) const ++attributes_written; } - auto depends = getDependencyUUIDs (); - if (depends.size() > 0) - { - out << ',' - << "\"depends\":["; + auto depends = getDependencyUUIDs(); + if (depends.size() > 0) { + out << ',' << "\"depends\":["; int count = 0; - for (const auto& dep : depends) - { - if (count++) - out << ','; + for (const auto& dep : depends) { + if (count++) out << ','; out << '"' << dep << '"'; } @@ -1049,32 +885,24 @@ std::string Task::composeJSON (bool decorate /*= false*/) const #ifdef PRODUCT_TASKWARRIOR // Include urgency. - if (decorate) - out << ',' - << "\"urgency\":" - << urgency_c (); + if (decorate) out << ',' << "\"urgency\":" << urgency_c(); #endif out << '}'; - return out.str (); + return out.str(); } //////////////////////////////////////////////////////////////////////////////// -int Task::getAnnotationCount () const -{ +int Task::getAnnotationCount() const { int count = 0; for (auto& ann : data) - if (! ann.first.compare (0, 11, "annotation_", 11)) - ++count; + if (!ann.first.compare(0, 11, "annotation_", 11)) ++count; return count; } //////////////////////////////////////////////////////////////////////////////// -bool Task::hasAnnotations () const -{ - return annotation_count ? true : false; -} +bool Task::hasAnnotations() const { return annotation_count ? true : false; } //////////////////////////////////////////////////////////////////////////////// // The timestamp is part of the name: @@ -1082,36 +910,29 @@ bool Task::hasAnnotations () const // // Note that the time is incremented (one second) in order to find a unique // timestamp. -void Task::addAnnotation (const std::string& description) -{ - time_t now = time (nullptr); +void Task::addAnnotation(const std::string& description) { + time_t now = time(nullptr); std::string key; - do - { - key = "annotation_" + format ((long long int) now); + do { + key = "annotation_" + format((long long int)now); ++now; - } - while (has (key)); + } while (has(key)); - data[key] = json::decode (description); + data[key] = json::decode(description); ++annotation_count; recalc_urgency = true; } //////////////////////////////////////////////////////////////////////////////// -void Task::removeAnnotations () -{ +void Task::removeAnnotations() { // Erase old annotations. - auto i = data.begin (); - while (i != data.end ()) - { - if (! i->first.compare (0, 11, "annotation_", 11)) - { + auto i = data.begin(); + while (i != data.end()) { + if (!i->first.compare(0, 11, "annotation_", 11)) { --annotation_count; - data.erase (i++); - } - else + data.erase(i++); + } else i++; } @@ -1119,44 +940,37 @@ void Task::removeAnnotations () } //////////////////////////////////////////////////////////////////////////////// -std::map Task::getAnnotations () const -{ - std::map a; +std::map Task::getAnnotations() const { + std::map a; for (auto& ann : data) - if (! ann.first.compare (0, 11, "annotation_", 11)) - a.insert (ann); + if (!ann.first.compare(0, 11, "annotation_", 11)) a.insert(ann); return a; } //////////////////////////////////////////////////////////////////////////////// -void Task::setAnnotations (const std::map & annotations) -{ +void Task::setAnnotations(const std::map& annotations) { // Erase old annotations. - removeAnnotations (); + removeAnnotations(); - for (auto& anno : annotations) - data.insert (anno); + for (auto& anno : annotations) data.insert(anno); - annotation_count = annotations.size (); + annotation_count = annotations.size(); recalc_urgency = true; } #ifdef PRODUCT_TASKWARRIOR //////////////////////////////////////////////////////////////////////////////// -void Task::addDependency (int depid) -{ +void Task::addDependency(int depid) { // Check that id is resolvable. - std::string uuid = Context::getContext ().tdb2.uuid (depid); - if (uuid == "") - throw format ("Could not create a dependency on task {1} - not found.", depid); + std::string uuid = Context::getContext().tdb2.uuid(depid); + if (uuid == "") throw format("Could not create a dependency on task {1} - not found.", depid); // the addDependency(&std::string) overload will check this, too, but here we // can give an more natural error message containing the id the user // provided. - if (hasDependency (uuid)) - { - Context::getContext ().footnote (format ("Task {1} already depends on task {2}.", id, depid)); + if (hasDependency(uuid)) { + Context::getContext().footnote(format("Task {1} already depends on task {2}.", id, depid)); return; } @@ -1165,26 +979,24 @@ void Task::addDependency (int depid) #endif //////////////////////////////////////////////////////////////////////////////// -void Task::addDependency (const std::string& uuid) -{ - if (uuid == get ("uuid")) - throw std::string ("A task cannot be dependent on itself."); +void Task::addDependency(const std::string& uuid) { + if (uuid == get("uuid")) throw std::string("A task cannot be dependent on itself."); - if (hasDependency (uuid)) - { + if (hasDependency(uuid)) { #ifdef PRODUCT_TASKWARRIOR - Context::getContext ().footnote (format ("Task {1} already depends on task {2}.", get ("uuid"), uuid)); + Context::getContext().footnote( + format("Task {1} already depends on task {2}.", get("uuid"), uuid)); #endif return; } // Store the dependency. - set (dep2Attr (uuid), "x"); + set(dep2Attr(uuid), "x"); // Prevent circular dependencies. #ifdef PRODUCT_TASKWARRIOR - if (dependencyIsCircular (*this)) - throw std::string ("Circular dependency detected and disallowed."); + if (dependencyIsCircular(*this)) + throw std::string("Circular dependency detected and disallowed."); #endif recalc_urgency = true; @@ -1193,106 +1005,94 @@ void Task::addDependency (const std::string& uuid) #ifdef PRODUCT_TASKWARRIOR //////////////////////////////////////////////////////////////////////////////// -void Task::removeDependency (int id) -{ - std::string uuid = Context::getContext ().tdb2.uuid (id); +void Task::removeDependency(int id) { + std::string uuid = Context::getContext().tdb2.uuid(id); // The removeDependency(std::string&) method will check this too, but here we // can give a more natural error message containing the id provided by the user - if (uuid == "" || !has (dep2Attr (uuid))) - throw format ("Could not delete a dependency on task {1} - not found.", id); - removeDependency (uuid); + if (uuid == "" || !has(dep2Attr(uuid))) + throw format("Could not delete a dependency on task {1} - not found.", id); + removeDependency(uuid); } //////////////////////////////////////////////////////////////////////////////// -void Task::removeDependency (const std::string& uuid) -{ - auto depattr = dep2Attr (uuid); - if (has (depattr)) - remove (depattr); +void Task::removeDependency(const std::string& uuid) { + auto depattr = dep2Attr(uuid); + if (has(depattr)) + remove(depattr); else - throw format ("Could not delete a dependency on task {1} - not found.", uuid); + throw format("Could not delete a dependency on task {1} - not found.", uuid); recalc_urgency = true; fixDependsAttribute(); } //////////////////////////////////////////////////////////////////////////////// -bool Task::hasDependency (const std::string& uuid) const -{ - auto depattr = dep2Attr (uuid); - return has (depattr); +bool Task::hasDependency(const std::string& uuid) const { + auto depattr = dep2Attr(uuid); + return has(depattr); } //////////////////////////////////////////////////////////////////////////////// -std::vector Task::getDependencyIDs () const -{ - std::vector ids; - for (auto& attr : all ()) { - if (!isDepAttr (attr)) - continue; - auto dep = attr2Dep (attr); - ids.push_back (Context::getContext ().tdb2.id (dep)); +std::vector Task::getDependencyIDs() const { + std::vector ids; + for (auto& attr : all()) { + if (!isDepAttr(attr)) continue; + auto dep = attr2Dep(attr); + ids.push_back(Context::getContext().tdb2.id(dep)); } return ids; } //////////////////////////////////////////////////////////////////////////////// -std::vector Task::getDependencyUUIDs () const -{ - std::vector uuids; - for (auto& attr : all ()) { - if (!isDepAttr (attr)) - continue; - auto dep = attr2Dep (attr); - uuids.push_back (dep); +std::vector Task::getDependencyUUIDs() const { + std::vector uuids; + for (auto& attr : all()) { + if (!isDepAttr(attr)) continue; + auto dep = attr2Dep(attr); + uuids.push_back(dep); } return uuids; } //////////////////////////////////////////////////////////////////////////////// -std::vector Task::getDependencyTasks () const -{ - auto uuids = getDependencyUUIDs (); +std::vector Task::getDependencyTasks() const { + auto uuids = getDependencyUUIDs(); // NOTE: this may seem inefficient, but note that `TDB2::get` performs a // linear search on each invocation, so scanning *once* is quite a bit more // efficient. - std::vector blocking; + std::vector blocking; if (uuids.size() > 0) - for (auto& it : Context::getContext ().tdb2.pending_tasks ()) - if (it.getStatus () != Task::completed && - it.getStatus () != Task::deleted && - std::find (uuids.begin (), uuids.end (), it.get ("uuid")) != uuids.end ()) - blocking.push_back (it); + for (auto& it : Context::getContext().tdb2.pending_tasks()) + if (it.getStatus() != Task::completed && it.getStatus() != Task::deleted && + std::find(uuids.begin(), uuids.end(), it.get("uuid")) != uuids.end()) + blocking.push_back(it); return blocking; } //////////////////////////////////////////////////////////////////////////////// -std::vector Task::getBlockedTasks () const -{ - auto uuid = get ("uuid"); +std::vector Task::getBlockedTasks() const { + auto uuid = get("uuid"); - std::vector blocked; - for (auto& it : Context::getContext ().tdb2.pending_tasks ()) - if (it.getStatus () != Task::completed && - it.getStatus () != Task::deleted && - it.hasDependency (uuid)) - blocked.push_back (it); + std::vector blocked; + for (auto& it : Context::getContext().tdb2.pending_tasks()) + if (it.getStatus() != Task::completed && it.getStatus() != Task::deleted && + it.hasDependency(uuid)) + blocked.push_back(it); return blocked; } #endif //////////////////////////////////////////////////////////////////////////////// -int Task::getTagCount () const -{ +int Task::getTagCount() const { auto count = 0; for (auto& attr : data) { - if (isTagAttr (attr.first)) { + if (isTagAttr(attr.first)) { count++; } } @@ -1310,229 +1110,203 @@ int Task::getTagCount () const // due:1month - - - - - - - ? // due:1year - - - - - - - - // -bool Task::hasTag (const std::string& tag) const -{ +bool Task::hasTag(const std::string& tag) const { // Synthetic tags - dynamically generated, but do not occupy storage space. // Note: This list must match that in CmdInfo::execute. // Note: This list must match that in ::feedback_reserved_tags. - if (isupper (tag[0])) - { + if (isupper(tag[0])) { // NOTE: This list should be kept synchronized with: // * the list in CmdTags.cpp for the _tags command. // * the list in CmdInfo.cpp for the info command. - if (tag == "BLOCKED") return is_blocked; + if (tag == "BLOCKED") return is_blocked; if (tag == "UNBLOCKED") return !is_blocked; - if (tag == "BLOCKING") return is_blocking; + if (tag == "BLOCKING") return is_blocking; #ifdef PRODUCT_TASKWARRIOR - if (tag == "READY") return is_ready (); - if (tag == "DUE") return is_due (); - if (tag == "DUETODAY") return is_duetoday (); // 2016-03-29: Deprecated in 2.6.0 - if (tag == "TODAY") return is_duetoday (); - if (tag == "YESTERDAY") return is_dueyesterday (); - if (tag == "TOMORROW") return is_duetomorrow (); - if (tag == "OVERDUE") return is_overdue (); - if (tag == "WEEK") return is_dueweek (); - if (tag == "MONTH") return is_duemonth (); - if (tag == "QUARTER") return is_duequarter (); - if (tag == "YEAR") return is_dueyear (); + if (tag == "READY") return is_ready(); + if (tag == "DUE") return is_due(); + if (tag == "DUETODAY") return is_duetoday(); // 2016-03-29: Deprecated in 2.6.0 + if (tag == "TODAY") return is_duetoday(); + if (tag == "YESTERDAY") return is_dueyesterday(); + if (tag == "TOMORROW") return is_duetomorrow(); + if (tag == "OVERDUE") return is_overdue(); + if (tag == "WEEK") return is_dueweek(); + if (tag == "MONTH") return is_duemonth(); + if (tag == "QUARTER") return is_duequarter(); + if (tag == "YEAR") return is_dueyear(); #endif - if (tag == "ACTIVE") return has ("start"); - if (tag == "SCHEDULED") return has ("scheduled"); - if (tag == "CHILD") return has ("parent") || has ("template"); // 2017-01-07: Deprecated in 2.6.0 - if (tag == "INSTANCE") return has ("template") || has ("parent"); - if (tag == "UNTIL") return has ("until"); - if (tag == "ANNOTATED") return hasAnnotations (); - if (tag == "TAGGED") return getTagCount() > 0; - if (tag == "PARENT") return has ("mask") || has ("last"); // 2017-01-07: Deprecated in 2.6.0 - if (tag == "TEMPLATE") return has ("last") || has ("mask"); - if (tag == "WAITING") return is_waiting (); - if (tag == "PENDING") return getStatus () == Task::pending; - if (tag == "COMPLETED") return getStatus () == Task::completed; - if (tag == "DELETED") return getStatus () == Task::deleted; + if (tag == "ACTIVE") return has("start"); + if (tag == "SCHEDULED") return has("scheduled"); + if (tag == "CHILD") return has("parent") || has("template"); // 2017-01-07: Deprecated in 2.6.0 + if (tag == "INSTANCE") return has("template") || has("parent"); + if (tag == "UNTIL") return has("until"); + if (tag == "ANNOTATED") return hasAnnotations(); + if (tag == "TAGGED") return getTagCount() > 0; + if (tag == "PARENT") return has("mask") || has("last"); // 2017-01-07: Deprecated in 2.6.0 + if (tag == "TEMPLATE") return has("last") || has("mask"); + if (tag == "WAITING") return is_waiting(); + if (tag == "PENDING") return getStatus() == Task::pending; + if (tag == "COMPLETED") return getStatus() == Task::completed; + if (tag == "DELETED") return getStatus() == Task::deleted; #ifdef PRODUCT_TASKWARRIOR - if (tag == "UDA") return is_udaPresent (); - if (tag == "ORPHAN") return is_orphanPresent (); - if (tag == "LATEST") return id == Context::getContext ().tdb2.latest_id (); + if (tag == "UDA") return is_udaPresent(); + if (tag == "ORPHAN") return is_orphanPresent(); + if (tag == "LATEST") return id == Context::getContext().tdb2.latest_id(); #endif - if (tag == "PROJECT") return has ("project"); - if (tag == "PRIORITY") return has ("priority"); + if (tag == "PROJECT") return has("project"); + if (tag == "PRIORITY") return has("priority"); } // Concrete tags. - if (has (tag2Attr (tag))) - return true; + if (has(tag2Attr(tag))) return true; return false; } //////////////////////////////////////////////////////////////////////////////// -void Task::addTag (const std::string& tag) -{ - auto attr = tag2Attr (tag); - if (!has (attr)) { - set (attr, "x"); +void Task::addTag(const std::string& tag) { + auto attr = tag2Attr(tag); + if (!has(attr)) { + set(attr, "x"); recalc_urgency = true; fixTagsAttribute(); } } //////////////////////////////////////////////////////////////////////////////// -void Task::setTags (const std::vector & tags) -{ +void Task::setTags(const std::vector& tags) { auto existing = getTags(); // edit in-place, determining which should be // added and which should be removed - std::vector toAdd; - std::vector toRemove; + std::vector toAdd; + std::vector toRemove; for (auto& tag : tags) { - if (std::find (existing.begin (), existing.end (), tag) == existing.end ()) - toAdd.push_back(tag); + if (std::find(existing.begin(), existing.end(), tag) == existing.end()) toAdd.push_back(tag); } - for (auto& tag : getTags ()) { - if (std::find (tags.begin (), tags.end (), tag) == tags.end ()) { - toRemove.push_back (tag); + for (auto& tag : getTags()) { + if (std::find(tags.begin(), tags.end(), tag) == tags.end()) { + toRemove.push_back(tag); } } for (auto& tag : toRemove) { - removeTag (tag); + removeTag(tag); } for (auto& tag : toAdd) { - addTag (tag); + addTag(tag); } // (note: addTag / removeTag took care of recalculating urgency) } //////////////////////////////////////////////////////////////////////////////// -std::vector Task::getTags () const -{ - std::vector tags; +std::vector Task::getTags() const { + std::vector tags; for (auto& attr : data) { - if (!isTagAttr (attr.first)) { + if (!isTagAttr(attr.first)) { continue; } - auto tag = attr2Tag (attr.first); - tags.push_back (tag); + auto tag = attr2Tag(attr.first); + tags.push_back(tag); } return tags; } //////////////////////////////////////////////////////////////////////////////// -void Task::removeTag (const std::string& tag) -{ - auto attr = tag2Attr (tag); - if (has (attr)) { - data.erase (attr); +void Task::removeTag(const std::string& tag) { + auto attr = tag2Attr(tag); + if (has(attr)) { + data.erase(attr); recalc_urgency = true; fixTagsAttribute(); } } //////////////////////////////////////////////////////////////////////////////// -void Task::fixTagsAttribute () -{ +void Task::fixTagsAttribute() { // Fix up the old `tags` attribute to match the `tag_..` attributes (or // remove it if there are no tags) - auto tags = getTags (); - if (tags.size () > 0) { - set ("tags", join (",", tags)); + auto tags = getTags(); + if (tags.size() > 0) { + set("tags", join(",", tags)); } else { - remove ("tags"); + remove("tags"); } } //////////////////////////////////////////////////////////////////////////////// -bool Task::isTagAttr(const std::string& attr) -{ - return attr.compare(0, 4, "tag_") == 0; -} +bool Task::isTagAttr(const std::string& attr) { return attr.compare(0, 4, "tag_") == 0; } //////////////////////////////////////////////////////////////////////////////// -const std::string Task::tag2Attr (const std::string& tag) const -{ +const std::string Task::tag2Attr(const std::string& tag) const { std::stringstream tag_attr; tag_attr << "tag_" << tag; return tag_attr.str(); } //////////////////////////////////////////////////////////////////////////////// -const std::string Task::attr2Tag (const std::string& attr) const -{ - assert (isTagAttr (attr)); +const std::string Task::attr2Tag(const std::string& attr) const { + assert(isTagAttr(attr)); return attr.substr(4); } //////////////////////////////////////////////////////////////////////////////// -void Task::fixDependsAttribute () -{ +void Task::fixDependsAttribute() { // Fix up the old `depends` attribute to match the `dep_..` attributes (or // remove it if there are no deps) - auto deps = getDependencyUUIDs (); - if (deps.size () > 0) { - set ("depends", join (",", deps)); + auto deps = getDependencyUUIDs(); + if (deps.size() > 0) { + set("depends", join(",", deps)); } else { - remove ("depends"); + remove("depends"); } } //////////////////////////////////////////////////////////////////////////////// -bool Task::isDepAttr(const std::string& attr) -{ - return attr.compare(0, 4, "dep_") == 0; -} +bool Task::isDepAttr(const std::string& attr) { return attr.compare(0, 4, "dep_") == 0; } //////////////////////////////////////////////////////////////////////////////// -const std::string Task::dep2Attr (const std::string& tag) const -{ +const std::string Task::dep2Attr(const std::string& tag) const { std::stringstream tag_attr; tag_attr << "dep_" << tag; return tag_attr.str(); } //////////////////////////////////////////////////////////////////////////////// -const std::string Task::attr2Dep (const std::string& attr) const -{ - assert (isDepAttr (attr)); +const std::string Task::attr2Dep(const std::string& attr) const { + assert(isDepAttr(attr)); return attr.substr(4); } //////////////////////////////////////////////////////////////////////////////// -bool Task::isAnnotationAttr(const std::string& attr) -{ +bool Task::isAnnotationAttr(const std::string& attr) { return attr.compare(0, 11, "annotation_") == 0; } #ifdef PRODUCT_TASKWARRIOR //////////////////////////////////////////////////////////////////////////////// // A UDA Orphan is an attribute that is not represented in context.columns. -std::vector Task::getUDAOrphans () const -{ - std::vector orphans; +std::vector Task::getUDAOrphans() const { + std::vector orphans; for (auto& it : data) - if (Context::getContext ().columns.find (it.first) == Context::getContext ().columns.end ()) - if (not (isAnnotationAttr (it.first) || isTagAttr (it.first) || isDepAttr (it.first))) - orphans.push_back (it.first); + if (Context::getContext().columns.find(it.first) == Context::getContext().columns.end()) + if (not(isAnnotationAttr(it.first) || isTagAttr(it.first) || isDepAttr(it.first))) + orphans.push_back(it.first); return orphans; } //////////////////////////////////////////////////////////////////////////////// -void Task::substitute ( - const std::string& from, - const std::string& to, - const std::string& flags) -{ - bool global = (flags.find ('g') != std::string::npos ? true : false); +void Task::substitute(const std::string& from, const std::string& to, const std::string& flags) { + bool global = (flags.find('g') != std::string::npos ? true : false); // Get the data to modify. - std::string description = get ("description"); - auto annotations = getAnnotations (); + std::string description = get("description"); + auto annotations = getAnnotations(); // Count the changes, so we know whether to proceed to annotations, after // modifying description. @@ -1540,103 +1314,94 @@ void Task::substitute ( bool done = false; // Regex support is optional. - if (Task::regex) - { + if (Task::regex) { // Create the regex. - RX rx (from, Task::searchCaseSensitive); - std::vector start; - std::vector end; + RX rx(from, Task::searchCaseSensitive); + std::vector start; + std::vector end; // Perform all subs on description. - if (rx.match (start, end, description)) - { + if (rx.match(start, end, description)) { int skew = 0; - for (unsigned int i = 0; i < start.size () && !done; ++i) - { - description.replace (start[i] + skew, end[i] - start[i], to); - skew += to.length () - (end[i] - start[i]); + for (unsigned int i = 0; i < start.size() && !done; ++i) { + description.replace(start[i] + skew, end[i] - start[i], to); + skew += to.length() - (end[i] - start[i]); ++changes; - if (!global) - done = true; + if (!global) done = true; } } - if (!done) - { + if (!done) { // Perform all subs on annotations. - for (auto& it : annotations) - { - start.clear (); - end.clear (); - if (rx.match (start, end, it.second)) - { + for (auto& it : annotations) { + start.clear(); + end.clear(); + if (rx.match(start, end, it.second)) { int skew = 0; - for (unsigned int i = 0; i < start.size () && !done; ++i) - { - it.second.replace (start[i + skew], end[i] - start[i], to); - skew += to.length () - (end[i] - start[i]); + for (unsigned int i = 0; i < start.size() && !done; ++i) { + it.second.replace(start[i + skew], end[i] - start[i], to); + skew += to.length() - (end[i] - start[i]); ++changes; - if (!global) - done = true; + if (!global) done = true; } } } } - } - else - { + } else { // Perform all subs on description. int counter = 0; std::string::size_type pos = 0; int skew = 0; - while ((pos = ::find (description, from, pos, Task::searchCaseSensitive)) != std::string::npos && !done) - { - description.replace (pos + skew, from.length (), to); - skew += to.length () - from.length (); + while ((pos = ::find(description, from, pos, Task::searchCaseSensitive)) != std::string::npos && + !done) { + description.replace(pos + skew, from.length(), to); + skew += to.length() - from.length(); - pos += to.length (); + pos += to.length(); ++changes; - if (!global) - done = true; + if (!global) done = true; if (++counter > APPROACHING_INFINITY) - throw format ("Terminated substitution because more than {1} changes were made - infinite loop protection.", APPROACHING_INFINITY); + throw format( + "Terminated substitution because more than {1} changes were made - infinite loop " + "protection.", + APPROACHING_INFINITY); } - if (!done) - { + if (!done) { // Perform all subs on annotations. counter = 0; - for (auto& anno : annotations) - { + for (auto& anno : annotations) { pos = 0; skew = 0; - while ((pos = ::find (anno.second, from, pos, Task::searchCaseSensitive)) != std::string::npos && !done) - { - anno.second.replace (pos + skew, from.length (), to); - skew += to.length () - from.length (); + while ((pos = ::find(anno.second, from, pos, Task::searchCaseSensitive)) != + std::string::npos && + !done) { + anno.second.replace(pos + skew, from.length(), to); + skew += to.length() - from.length(); - pos += to.length (); + pos += to.length(); ++changes; - if (!global) - done = true; + if (!global) done = true; if (++counter > APPROACHING_INFINITY) - throw format ("Terminated substitution because more than {1} changes were made - infinite loop protection.", APPROACHING_INFINITY); + throw format( + "Terminated substitution because more than {1} changes were made - infinite loop " + "protection.", + APPROACHING_INFINITY); } } } } - if (changes) - { - set ("description", description); - setAnnotations (annotations); + if (changes) { + set("description", description); + setAnnotations(annotations); recalc_urgency = true; } } @@ -1651,149 +1416,116 @@ void Task::substitute ( // // Critically, note that despite the name this is not a read-only function. // -void Task::validate (bool applyDefault /* = true */) -{ +void Task::validate(bool applyDefault /* = true */) { Task::status status = Task::pending; - if (get ("status") != "") - status = getStatus (); + if (get("status") != "") status = getStatus(); // 1) Provide missing attributes where possible // Provide a UUID if necessary. Validate if present. - std::string uid = get ("uuid"); - if (has ("uuid") && uid != "") - { - Lexer lex (uid); + std::string uid = get("uuid"); + if (has("uuid") && uid != "") { + Lexer lex(uid); std::string token; Lexer::Type type; - if (! lex.isUUID (token, type, true)) - throw format ("Not a valid UUID '{1}'.", uid); - } - else - set ("uuid", uuid ()); + if (!lex.isUUID(token, type, true)) throw format("Not a valid UUID '{1}'.", uid); + } else + set("uuid", uuid()); // TODO Obsolete remove for 3.0.0 // Recurring tasks get a special status. - if (status == Task::pending && - has ("due") && - has ("recur") && - (! has ("parent") || get ("parent") == "") && - (! has ("template") || get ("template") == "")) - { + if (status == Task::pending && has("due") && has("recur") && + (!has("parent") || get("parent") == "") && (!has("template") || get("template") == "")) { status = Task::recurring; } -/* - // TODO Add for 3.0.0 - if (status == Task::pending && - has ("due") && - has ("recur") && - (! has ("template") || get ("template") == "")) - { - status = Task::recurring; - } -*/ + /* + // TODO Add for 3.0.0 + if (status == Task::pending && + has ("due") && + has ("recur") && + (! has ("template") || get ("template") == "")) + { + status = Task::recurring; + } + */ // Tasks with a wait: date get a special status. - else if (status == Task::pending && - has ("wait") && - get ("wait") != "") + else if (status == Task::pending && has("wait") && get("wait") != "") status = Task::waiting; // By default, tasks are pending. - else if (! has ("status") || get ("status") == "") + else if (!has("status") || get("status") == "") status = Task::pending; // Default to 'periodic' type recurrence. - if (status == Task::recurring && - (! has ("rtype") || get ("rtype") == "")) - { - set ("rtype", "periodic"); + if (status == Task::recurring && (!has("rtype") || get("rtype") == "")) { + set("rtype", "periodic"); } // Store the derived status. - setStatus (status); + setStatus(status); #ifdef PRODUCT_TASKWARRIOR // Provide an entry date unless user already specified one. - if (! has ("entry") || get ("entry") == "") - setAsNow ("entry"); + if (!has("entry") || get("entry") == "") setAsNow("entry"); // Completed tasks need an end date, so inherit the entry date. - if ((status == Task::completed || status == Task::deleted) && - (! has ("end") || get ("end") == "")) - setAsNow ("end"); + if ((status == Task::completed || status == Task::deleted) && (!has("end") || get("end") == "")) + setAsNow("end"); // Pending tasks cannot have an end date, remove if present - if ((status == Task::pending) && (get ("end") != "")) - remove ("end"); + if ((status == Task::pending) && (get("end") != "")) remove("end"); // Provide a modified date unless user already specified one. - if (! has ("modified") || get ("modified") == "") - setAsNow ("modified"); + if (!has("modified") || get("modified") == "") setAsNow("modified"); - if (applyDefault && (! has ("parent") || get ("parent") == "")) - { + if (applyDefault && (!has("parent") || get("parent") == "")) { // Override with default.project, if not specified. - if (Task::defaultProject != "" && - ! has ("project")) - { - if (Context::getContext ().columns["project"]->validate (Task::defaultProject)) - set ("project", Task::defaultProject); + if (Task::defaultProject != "" && !has("project")) { + if (Context::getContext().columns["project"]->validate(Task::defaultProject)) + set("project", Task::defaultProject); } // Override with default.due, if not specified. - if (Task::defaultDue != "" && - ! has ("due")) - { - if (Context::getContext ().columns["due"]->validate (Task::defaultDue)) - { - Duration dur (Task::defaultDue); - if (dur.toTime_t () != 0) - set ("due", (Datetime () + dur.toTime_t ()).toEpoch ()); + if (Task::defaultDue != "" && !has("due")) { + if (Context::getContext().columns["due"]->validate(Task::defaultDue)) { + Duration dur(Task::defaultDue); + if (dur.toTime_t() != 0) + set("due", (Datetime() + dur.toTime_t()).toEpoch()); else - set ("due", Datetime (Task::defaultDue).toEpoch ()); + set("due", Datetime(Task::defaultDue).toEpoch()); } } // Override with default.scheduled, if not specified. - if (Task::defaultScheduled != "" && - ! has ("scheduled")) - { - if (Context::getContext ().columns["scheduled"]->validate (Task::defaultScheduled)) - { - Duration dur (Task::defaultScheduled); - if (dur.toTime_t () != 0) - set ("scheduled", (Datetime () + dur.toTime_t ()).toEpoch ()); + if (Task::defaultScheduled != "" && !has("scheduled")) { + if (Context::getContext().columns["scheduled"]->validate(Task::defaultScheduled)) { + Duration dur(Task::defaultScheduled); + if (dur.toTime_t() != 0) + set("scheduled", (Datetime() + dur.toTime_t()).toEpoch()); else - set ("scheduled", Datetime (Task::defaultScheduled).toEpoch ()); + set("scheduled", Datetime(Task::defaultScheduled).toEpoch()); } } // If a UDA has a default value in the configuration, // override with uda.(uda).default, if not specified. // Gather a list of all UDAs with a .default value - std::vector udas; - for (auto& var : Context::getContext ().config) - { - if (! var.first.compare (0, 4, "uda.", 4) && - var.first.find (".default") != std::string::npos) - { - auto period = var.first.find ('.', 4); - if (period != std::string::npos) - udas.push_back (var.first.substr (4, period - 4)); + std::vector udas; + for (auto& var : Context::getContext().config) { + if (!var.first.compare(0, 4, "uda.", 4) && var.first.find(".default") != std::string::npos) { + auto period = var.first.find('.', 4); + if (period != std::string::npos) udas.push_back(var.first.substr(4, period - 4)); } } - if (udas.size ()) - { + if (udas.size()) { // For each of those, setup the default value on the task now, // of course only if we don't have one on the command line already - for (auto& uda : udas) - { - std::string defVal= Context::getContext ().config.get ("uda." + uda + ".default"); + for (auto& uda : udas) { + std::string defVal = Context::getContext().config.get("uda." + uda + ".default"); // If the default is empty, or we already have a value, skip it - if (defVal != "" && get (uda) == "") - set (uda, defVal); + if (defVal != "" && get(uda) == "") set(uda, defVal); } } } @@ -1802,54 +1534,50 @@ void Task::validate (bool applyDefault /* = true */) // 2) To provide suitable warnings about odd states // Date relationships. - validate_before ("wait", "due"); - validate_before ("entry", "start"); - validate_before ("entry", "end"); - validate_before ("wait", "scheduled"); - validate_before ("scheduled", "start"); - validate_before ("scheduled", "due"); - validate_before ("scheduled", "end"); + validate_before("wait", "due"); + validate_before("entry", "start"); + validate_before("entry", "end"); + validate_before("wait", "scheduled"); + validate_before("scheduled", "start"); + validate_before("scheduled", "due"); + validate_before("scheduled", "end"); // 3) To generate errors when the inconsistencies are not fixable // There is no fixing a missing description. - if (! has ("description")) - throw std::string ("A task must have a description."); - else if (get ("description") == "") - throw std::string ("Cannot add a task that is blank."); + if (!has("description")) + throw std::string("A task must have a description."); + else if (get("description") == "") + throw std::string("Cannot add a task that is blank."); // Cannot have a recur frequency with no due date - when would it recur? - if (has ("recur") && (! has ("due") || get ("due") == "")) - throw std::string ("A recurring task must also have a 'due' date."); + if (has("recur") && (!has("due") || get("due") == "")) + throw std::string("A recurring task must also have a 'due' date."); // Recur durations must be valid. - if (has ("recur")) - { - std::string value = get ("recur"); - if (value != "") - { + if (has("recur")) { + std::string value = get("recur"); + if (value != "") { Duration p; std::string::size_type i = 0; - if (! p.parse (value, i)) + if (!p.parse(value, i)) // TODO Ideal location to map unsupported old recurrence periods to supported values. - throw format ("The recurrence value '{1}' is not valid.", value); + throw format("The recurrence value '{1}' is not valid.", value); } } } //////////////////////////////////////////////////////////////////////////////// -void Task::validate_before (const std::string& left, const std::string& right) -{ +void Task::validate_before(const std::string& left, const std::string& right) { #ifdef PRODUCT_TASKWARRIOR - if (has (left) && - has (right)) - { - Datetime date_left (get_date (left)); - Datetime date_right (get_date (right)); + if (has(left) && has(right)) { + Datetime date_left(get_date(left)); + Datetime date_right(get_date(right)); // if date is zero, then it is being removed (e.g. "due: wait:1day") - if (date_left > date_right && date_right.toEpoch () != 0) - Context::getContext ().footnote (format ("Warning: You have specified that the '{1}' date is after the '{2}' date.", left, right)); + if (date_left > date_right && date_right.toEpoch() != 0) + Context::getContext().footnote(format( + "Warning: You have specified that the '{1}' date is after the '{2}' date.", left, right)); } #endif } @@ -1858,53 +1586,58 @@ void Task::validate_before (const std::string& left, const std::string& right) // Encode values prior to serialization. // [ -> &open; // ] -> &close; -const std::string Task::encode (const std::string& value) const -{ - auto modified = str_replace (value, "[", "&open;"); - return str_replace (modified, "]", "&close;"); +const std::string Task::encode(const std::string& value) const { + auto modified = str_replace(value, "[", "&open;"); + return str_replace(modified, "]", "&close;"); } //////////////////////////////////////////////////////////////////////////////// // Decode values after parse. // [ <- &open; // ] <- &close; -const std::string Task::decode (const std::string& value) const -{ - if (value.find ('&') == std::string::npos) - return value; +const std::string Task::decode(const std::string& value) const { + if (value.find('&') == std::string::npos) return value; - auto modified = str_replace (value, "&open;", "["); - return str_replace (modified, "&close;", "]"); + auto modified = str_replace(value, "&open;", "["); + return str_replace(modified, "&close;", "]"); } //////////////////////////////////////////////////////////////////////////////// -tc::Status Task::status2tc (const Task::status status) -{ +tc::Status Task::status2tc(const Task::status status) { switch (status) { - case Task::pending: return tc::Status::Pending; - case Task::completed: return tc::Status::Completed; - case Task::deleted: return tc::Status::Deleted; - case Task::waiting: return tc::Status::Pending; // waiting is no longer a status - case Task::recurring: return tc::Status::Recurring; - default: return tc::Status::Unknown; + case Task::pending: + return tc::Status::Pending; + case Task::completed: + return tc::Status::Completed; + case Task::deleted: + return tc::Status::Deleted; + case Task::waiting: + return tc::Status::Pending; // waiting is no longer a status + case Task::recurring: + return tc::Status::Recurring; + default: + return tc::Status::Unknown; } } //////////////////////////////////////////////////////////////////////////////// -Task::status Task::tc2status (const tc::Status status) -{ +Task::status Task::tc2status(const tc::Status status) { switch (status) { - case tc::Status::Pending: return Task::pending; - case tc::Status::Completed: return Task::completed; - case tc::Status::Deleted: return Task::deleted; - case tc::Status::Recurring: return Task::recurring; - default: return Task::pending; + case tc::Status::Pending: + return Task::pending; + case tc::Status::Completed: + return Task::completed; + case tc::Status::Deleted: + return Task::deleted; + case tc::Status::Recurring: + return Task::recurring; + default: + return Task::pending; } } //////////////////////////////////////////////////////////////////////////////// -int Task::determineVersion (const std::string& line) -{ +int Task::determineVersion(const std::string& line) { // Version 2 looks like: // // uuid status [tags] [attributes] description\n @@ -1915,23 +1648,17 @@ int Task::determineVersion (const std::string& line) // // Scan for the hyphens in the uuid, the following space, and a valid status // character. - if (line[8] == '-' && - line[13] == '-' && - line[18] == '-' && - line[23] == '-' && - line[36] == ' ' && - (line[37] == '-' || line[37] == '+' || line[37] == 'X' || line[37] == 'r')) - { + if (line[8] == '-' && line[13] == '-' && line[18] == '-' && line[23] == '-' && line[36] == ' ' && + (line[37] == '-' || line[37] == '+' || line[37] == 'X' || line[37] == 'r')) { // Version 3 looks like: // // uuid status [tags] [attributes] [annotations] description\n // // Scan for the number of [] pairs. - auto tagAtts = line.find ("] [", 0); - auto attsAnno = line.find ("] [", tagAtts + 1); - auto annoDesc = line.find ("] ", attsAnno + 1); - if (tagAtts != std::string::npos && - attsAnno != std::string::npos && + auto tagAtts = line.find("] [", 0); + auto attsAnno = line.find("] [", tagAtts + 1); + auto annoDesc = line.find("] ", attsAnno + 1); + if (tagAtts != std::string::npos && attsAnno != std::string::npos && annoDesc != std::string::npos) return 3; else @@ -1943,9 +1670,8 @@ int Task::determineVersion (const std::string& line) // [name:"value" ...] // // Scan for [, ] and :". - else if (line[0] == '[' && - line[line.length () - 1] == ']' && - line.find ("uuid:\"") != std::string::npos) + else if (line[0] == '[' && line[line.length() - 1] == ']' && + line.find("uuid:\"") != std::string::npos) return 4; // Version 1 looks like: @@ -1954,10 +1680,8 @@ int Task::determineVersion (const std::string& line) // X [tags] [attributes] description\n // // Scan for the first character being either the bracket or X. - else if (line.find ("X [") == 0 || - (line[0] == '[' && - line.substr (line.length () - 1, 1) != "]" && - line.length () > 3)) + else if (line.find("X [") == 0 || + (line[0] == '[' && line.substr(line.length() - 1, 1) != "]" && line.length() > 3)) return 1; // Version 5? @@ -1990,98 +1714,97 @@ int Task::determineVersion (const std::string& line) // // See rfc31-urgency.txt for full details. // -float Task::urgency_c () const -{ +float Task::urgency_c() const { float value = 0.0; #ifdef PRODUCT_TASKWARRIOR - value += fabsf (Task::urgencyProjectCoefficient) > epsilon ? (urgency_project () * Task::urgencyProjectCoefficient) : 0.0; - value += fabsf (Task::urgencyActiveCoefficient) > epsilon ? (urgency_active () * Task::urgencyActiveCoefficient) : 0.0; - value += fabsf (Task::urgencyScheduledCoefficient) > epsilon ? (urgency_scheduled () * Task::urgencyScheduledCoefficient) : 0.0; - value += fabsf (Task::urgencyWaitingCoefficient) > epsilon ? (urgency_waiting () * Task::urgencyWaitingCoefficient) : 0.0; - value += fabsf (Task::urgencyBlockedCoefficient) > epsilon ? (urgency_blocked () * Task::urgencyBlockedCoefficient) : 0.0; - value += fabsf (Task::urgencyAnnotationsCoefficient) > epsilon ? (urgency_annotations () * Task::urgencyAnnotationsCoefficient) : 0.0; - value += fabsf (Task::urgencyTagsCoefficient) > epsilon ? (urgency_tags () * Task::urgencyTagsCoefficient) : 0.0; - value += fabsf (Task::urgencyDueCoefficient) > epsilon ? (urgency_due () * Task::urgencyDueCoefficient) : 0.0; - value += fabsf (Task::urgencyBlockingCoefficient) > epsilon ? (urgency_blocking () * Task::urgencyBlockingCoefficient) : 0.0; - value += fabsf (Task::urgencyAgeCoefficient) > epsilon ? (urgency_age () * Task::urgencyAgeCoefficient) : 0.0; + value += fabsf(Task::urgencyProjectCoefficient) > epsilon + ? (urgency_project() * Task::urgencyProjectCoefficient) + : 0.0; + value += fabsf(Task::urgencyActiveCoefficient) > epsilon + ? (urgency_active() * Task::urgencyActiveCoefficient) + : 0.0; + value += fabsf(Task::urgencyScheduledCoefficient) > epsilon + ? (urgency_scheduled() * Task::urgencyScheduledCoefficient) + : 0.0; + value += fabsf(Task::urgencyWaitingCoefficient) > epsilon + ? (urgency_waiting() * Task::urgencyWaitingCoefficient) + : 0.0; + value += fabsf(Task::urgencyBlockedCoefficient) > epsilon + ? (urgency_blocked() * Task::urgencyBlockedCoefficient) + : 0.0; + value += fabsf(Task::urgencyAnnotationsCoefficient) > epsilon + ? (urgency_annotations() * Task::urgencyAnnotationsCoefficient) + : 0.0; + value += fabsf(Task::urgencyTagsCoefficient) > epsilon + ? (urgency_tags() * Task::urgencyTagsCoefficient) + : 0.0; + value += fabsf(Task::urgencyDueCoefficient) > epsilon + ? (urgency_due() * Task::urgencyDueCoefficient) + : 0.0; + value += fabsf(Task::urgencyBlockingCoefficient) > epsilon + ? (urgency_blocking() * Task::urgencyBlockingCoefficient) + : 0.0; + value += fabsf(Task::urgencyAgeCoefficient) > epsilon + ? (urgency_age() * Task::urgencyAgeCoefficient) + : 0.0; const std::string taskProjectName = get("project"); // Tag- and project-specific coefficients. - for (auto& var : Task::coefficients) - { - if (fabs (var.second) > epsilon) - { - if (! var.first.compare (0, 13, "urgency.user.", 13)) - { + for (auto& var : Task::coefficients) { + if (fabs(var.second) > epsilon) { + if (!var.first.compare(0, 13, "urgency.user.", 13)) { // urgency.user.project..coefficient auto end = std::string::npos; - if (var.first.substr (13, 8) == "project." && - (end = var.first.find (".coefficient")) != std::string::npos) - { - std::string project = var.first.substr (21, end - 21); + if (var.first.substr(13, 8) == "project." && + (end = var.first.find(".coefficient")) != std::string::npos) { + std::string project = var.first.substr(21, end - 21); - if (taskProjectName == project || - taskProjectName.find(project + '.') == 0) - { + if (taskProjectName == project || taskProjectName.find(project + '.') == 0) { value += var.second; } } // urgency.user.tag..coefficient - if (var.first.substr (13, 4) == "tag." && - (end = var.first.find (".coefficient")) != std::string::npos) - { - std::string tag = var.first.substr (17, end - 17); + if (var.first.substr(13, 4) == "tag." && + (end = var.first.find(".coefficient")) != std::string::npos) { + std::string tag = var.first.substr(17, end - 17); - if (hasTag (tag)) - value += var.second; + if (hasTag(tag)) value += var.second; } // urgency.user.keyword..coefficient - if (var.first.substr (13, 8) == "keyword." && - (end = var.first.find (".coefficient")) != std::string::npos) - { - std::string keyword = var.first.substr (21, end - 21); + if (var.first.substr(13, 8) == "keyword." && + (end = var.first.find(".coefficient")) != std::string::npos) { + std::string keyword = var.first.substr(21, end - 21); - if (get ("description").find (keyword) != std::string::npos) - value += var.second; + if (get("description").find(keyword) != std::string::npos) value += var.second; } - } - else if (var.first.substr (0, 12) == "urgency.uda.") - { + } else if (var.first.substr(0, 12) == "urgency.uda.") { // urgency.uda..coefficient // urgency.uda...coefficient - auto end = var.first.find (".coefficient"); - if (end != std::string::npos) - { - const std::string uda = var.first.substr (12, end - 12); - auto dot = uda.find ('.'); - if (dot == std::string::npos) - { + auto end = var.first.find(".coefficient"); + if (end != std::string::npos) { + const std::string uda = var.first.substr(12, end - 12); + auto dot = uda.find('.'); + if (dot == std::string::npos) { // urgency.uda..coefficient - if (has (uda)) - value += var.second; - } - else - { + if (has(uda)) value += var.second; + } else { // urgency.uda...coefficient - if (get (uda.substr(0, dot)) == uda.substr(dot+1)) - value += var.second; + if (get(uda.substr(0, dot)) == uda.substr(dot + 1)) value += var.second; } } } } } - if (is_blocking && Context::getContext ().config.getBoolean ("urgency.inherit")) - { + if (is_blocking && Context::getContext().config.getBoolean("urgency.inherit")) { float prev = value; - value = std::max (value, urgency_inherit ()); + value = std::max(value, urgency_inherit()); // This is a hackish way of making sure parent tasks are sorted above // child tasks. For reports that hide blocked tasks, this is not needed. - if (prev <= value) - value += 0.01; + if (prev <= value) value += 0.01; } #endif @@ -2089,11 +1812,9 @@ float Task::urgency_c () const } //////////////////////////////////////////////////////////////////////////////// -float Task::urgency () -{ - if (recalc_urgency) - { - urgency_value = urgency_c (); +float Task::urgency() { + if (recalc_urgency) { + urgency_value = urgency_c(); // Return the sum of all terms. recalc_urgency = false; @@ -2103,16 +1824,14 @@ float Task::urgency () } //////////////////////////////////////////////////////////////////////////////// -float Task::urgency_inherit () const -{ +float Task::urgency_inherit() const { float v = -FLT_MAX; #ifdef PRODUCT_TASKWARRIOR // Calling getBlockedTasks is rather expensive. // It is called recursively for each dependency in the chain here. - for (auto& task : getBlockedTasks ()) - { + for (auto& task : getBlockedTasks()) { // Find highest urgency in all blocked tasks. - v = std::max (v, task.urgency ()); + v = std::max(v, task.urgency()); } #endif @@ -2120,71 +1839,64 @@ float Task::urgency_inherit () const } //////////////////////////////////////////////////////////////////////////////// -float Task::urgency_project () const -{ - if (has ("project")) - return 1.0; +float Task::urgency_project() const { + if (has("project")) return 1.0; return 0.0; } //////////////////////////////////////////////////////////////////////////////// -float Task::urgency_active () const -{ - if (has ("start")) - return 1.0; +float Task::urgency_active() const { + if (has("start")) return 1.0; return 0.0; } //////////////////////////////////////////////////////////////////////////////// -float Task::urgency_scheduled () const -{ - if (has ("scheduled") && - get_date ("scheduled") < time (nullptr)) - return 1.0; +float Task::urgency_scheduled() const { + if (has("scheduled") && get_date("scheduled") < time(nullptr)) return 1.0; return 0.0; } //////////////////////////////////////////////////////////////////////////////// -float Task::urgency_waiting () const -{ - if (is_waiting ()) - return 1.0; +float Task::urgency_waiting() const { + if (is_waiting()) return 1.0; return 0.0; } //////////////////////////////////////////////////////////////////////////////// // A task is blocked only if the task it depends upon is pending/waiting. -float Task::urgency_blocked () const -{ - if (is_blocked) +float Task::urgency_blocked() const { + if (is_blocked) return 1.0; + + return 0.0; +} + +//////////////////////////////////////////////////////////////////////////////// +float Task::urgency_annotations() const { + if (annotation_count >= 3) return 1.0; + else if (annotation_count == 2) + return 0.9; + else if (annotation_count == 1) + return 0.8; return 0.0; } //////////////////////////////////////////////////////////////////////////////// -float Task::urgency_annotations () const -{ - if (annotation_count >= 3) return 1.0; - else if (annotation_count == 2) return 0.9; - else if (annotation_count == 1) return 0.8; - - return 0.0; -} - -//////////////////////////////////////////////////////////////////////////////// -float Task::urgency_tags () const -{ - switch (getTagCount ()) - { - case 0: return 0.0; - case 1: return 0.8; - case 2: return 0.9; - default: return 1.0; +float Task::urgency_tags() const { + switch (getTagCount()) { + case 0: + return 0.0; + case 1: + return 0.8; + case 2: + return 0.9; + default: + return 1.0; } } @@ -2199,44 +1911,40 @@ float Task::urgency_tags () const // capped capped // // -float Task::urgency_due () const -{ - if (has ("due")) - { +float Task::urgency_due() const { + if (has("due")) { Datetime now; - Datetime due (get_date ("due")); + Datetime due(get_date("due")); // Map a range of 21 days to the value 0.2 - 1.0 float days_overdue = (now - due) / 86400.0; - if (days_overdue >= 7.0) return 1.0; // < 1 wk ago - else if (days_overdue >= -14.0) return ((days_overdue + 14.0) * 0.8 / 21.0) + 0.2; - else return 0.2; // > 2 wks + if (days_overdue >= 7.0) + return 1.0; // < 1 wk ago + else if (days_overdue >= -14.0) + return ((days_overdue + 14.0) * 0.8 / 21.0) + 0.2; + else + return 0.2; // > 2 wks } return 0.0; } //////////////////////////////////////////////////////////////////////////////// -float Task::urgency_age () const -{ - if (!has ("entry")) - return 1.0; +float Task::urgency_age() const { + if (!has("entry")) return 1.0; Datetime now; - Datetime entry (get_date ("entry")); + Datetime entry(get_date("entry")); int age = (now - entry) / 86400; // in days - if (Task::urgencyAgeMax == 0 || age > Task::urgencyAgeMax) - return 1.0; + if (Task::urgencyAgeMax == 0 || age > Task::urgencyAgeMax) return 1.0; return (1.0 * age / Task::urgencyAgeMax); } //////////////////////////////////////////////////////////////////////////////// -float Task::urgency_blocking () const -{ - if (is_blocking) - return 1.0; +float Task::urgency_blocking() const { + if (is_blocking) return 1.0; return 0.0; } @@ -2248,169 +1956,138 @@ float Task::urgency_blocking () const // well as reducing the object depdendencies of Task. // // It came from the Command base object, but doesn't really belong there either. -void Task::modify (modType type, bool text_required /* = false */) -{ +void Task::modify(modType type, bool text_required /* = false */) { std::string label = " MODIFICATION "; // while reading the parse tree, consider DOM references in the context of // this task - auto currentTask = Context::getContext ().withCurrentTask(this); + auto currentTask = Context::getContext().withCurrentTask(this); // Need this for later comparison. - auto originalStatus = getStatus (); + auto originalStatus = getStatus(); std::string text = ""; bool mods = false; - for (auto& a : Context::getContext ().cli2._args) - { - if (a.hasTag ("MODIFICATION")) - { - if (a._lextype == Lexer::Type::pair) - { + for (auto& a : Context::getContext().cli2._args) { + if (a.hasTag("MODIFICATION")) { + if (a._lextype == Lexer::Type::pair) { // 'canonical' is the canonical name. Needs to be said. // 'value' requires eval. - std::string name = a.attribute ("canonical"); - std::string value = a.attribute ("value"); - if (value == "" || - value == "''" || - value == "\"\"") - { + std::string name = a.attribute("canonical"); + std::string value = a.attribute("value"); + if (value == "" || value == "''" || value == "\"\"") { // Special case: Handle bulk removal of 'tags' and 'depends" virtual // attributes - if (name == "depends") - { - for (auto dep: getDependencyUUIDs ()) - removeDependency(dep); - } - else if (name == "tags") - { - for (auto tag: getTags ()) - removeTag(tag); + if (name == "depends") { + for (auto dep : getDependencyUUIDs()) removeDependency(dep); + } else if (name == "tags") { + for (auto tag : getTags()) removeTag(tag); } // ::composeF4 will skip if the value is blank, but the presence of // the attribute will prevent ::validate from applying defaults. - if ((has (name) && get (name) != "") || - (name == "due" && Context::getContext ().config.has ("default.due")) || - (name == "scheduled" && Context::getContext ().config.has ("default.scheduled")) || - (name == "project" && Context::getContext ().config.has ("default.project"))) - { + if ((has(name) && get(name) != "") || + (name == "due" && Context::getContext().config.has("default.due")) || + (name == "scheduled" && Context::getContext().config.has("default.scheduled")) || + (name == "project" && Context::getContext().config.has("default.project"))) { mods = true; - set (name, ""); + set(name, ""); } - Context::getContext ().debug (label + name + " <-- ''"); - } - else - { - Lexer::dequote (value); + Context::getContext().debug(label + name + " <-- ''"); + } else { + Lexer::dequote(value); // Get the column info. Some columns are not modifiable. - Column* column = Context::getContext ().columns[name]; - if (! column || - ! column->modifiable ()) - throw format ("The '{1}' attribute does not allow a value of '{2}'.", name, value); + Column* column = Context::getContext().columns[name]; + if (!column || !column->modifiable()) + throw format("The '{1}' attribute does not allow a value of '{2}'.", name, value); // Delegate modification to the column object or their base classes. - if (name == "depends" || - name == "tags" || - name == "recur" || - column->type () == "date" || - column->type () == "duration" || - column->type () == "numeric" || - column->type () == "string") - { - column->modify (*this, value); + if (name == "depends" || name == "tags" || name == "recur" || column->type() == "date" || + column->type() == "duration" || column->type() == "numeric" || + column->type() == "string") { + column->modify(*this, value); mods = true; } else - throw format ("Unrecognized column type '{1}' for column '{2}'", column->type (), name); + throw format("Unrecognized column type '{1}' for column '{2}'", column->type(), name); } } // Perform description/annotation substitution. - else if (a._lextype == Lexer::Type::substitution) - { - Context::getContext ().debug (label + "substitute " + a.attribute ("raw")); - substitute (a.attribute ("from"), - a.attribute ("to"), - a.attribute ("flags")); + else if (a._lextype == Lexer::Type::substitution) { + Context::getContext().debug(label + "substitute " + a.attribute("raw")); + substitute(a.attribute("from"), a.attribute("to"), a.attribute("flags")); mods = true; } // Tags need special handling because they are essentially a vector stored // in a single string, therefore Task::{add,remove}Tag must be called as // appropriate. - else if (a._lextype == Lexer::Type::tag) - { - std::string tag = a.attribute ("name"); - feedback_reserved_tags (tag); + else if (a._lextype == Lexer::Type::tag) { + std::string tag = a.attribute("name"); + feedback_reserved_tags(tag); - if (a.attribute ("sign") == "+") - { - Context::getContext ().debug (label + "tags <-- add '" + tag + '\''); - addTag (tag); - feedback_special_tags (*this, tag); - } - else - { - Context::getContext ().debug (label + "tags <-- remove '" + tag + '\''); - removeTag (tag); + if (a.attribute("sign") == "+") { + Context::getContext().debug(label + "tags <-- add '" + tag + '\''); + addTag(tag); + feedback_special_tags(*this, tag); + } else { + Context::getContext().debug(label + "tags <-- remove '" + tag + '\''); + removeTag(tag); } mods = true; } // Unknown args are accumulated as though they were WORDs. - else - { - if (text != "") - text += ' '; - text += a.attribute ("raw"); + else { + if (text != "") text += ' '; + text += a.attribute("raw"); } } } // Task::modType determines what happens to the WORD arguments, if there are // any. - if (text != "") - { - Lexer::dequote (text); + if (text != "") { + Lexer::dequote(text); - switch (type) - { - case modReplace: - Context::getContext ().debug (label + "description <-- '" + text + '\''); - set ("description", text); - break; + switch (type) { + case modReplace: + Context::getContext().debug(label + "description <-- '" + text + '\''); + set("description", text); + break; - case modPrepend: - Context::getContext ().debug (label + "description <-- '" + text + "' + description"); - set ("description", text + ' ' + get ("description")); - break; + case modPrepend: + Context::getContext().debug(label + "description <-- '" + text + "' + description"); + set("description", text + ' ' + get("description")); + break; - case modAppend: - Context::getContext ().debug (label + "description <-- description + '" + text + '\''); - set ("description", get ("description") + ' ' + text); - break; + case modAppend: + Context::getContext().debug(label + "description <-- description + '" + text + '\''); + set("description", get("description") + ' ' + text); + break; - case modAnnotate: - Context::getContext ().debug (label + "new annotation <-- '" + text + '\''); - addAnnotation (text); - break; + case modAnnotate: + Context::getContext().debug(label + "new annotation <-- '" + text + '\''); + addAnnotation(text); + break; } - } - else if (! mods && text_required) - throw std::string ("Additional text must be provided."); + } else if (!mods && text_required) + throw std::string("Additional text must be provided."); // Modifying completed/deleted tasks generates a message, if the modification // does not change status. - if ((getStatus () == Task::completed || getStatus () == Task::deleted) && - getStatus () == originalStatus) - { - auto uuid = get ("uuid").substr (0, 8); - Context::getContext ().footnote (format ("Note: Modified task {1} is {2}. You may wish to make this task pending with: task {3} modify status:pending", uuid, get ("status"), uuid)); + if ((getStatus() == Task::completed || getStatus() == Task::deleted) && + getStatus() == originalStatus) { + auto uuid = get("uuid").substr(0, 8); + Context::getContext().footnote( + format("Note: Modified task {1} is {2}. You may wish to make this task pending with: task " + "{3} modify status:pending", + uuid, get("status"), uuid)); } } #endif @@ -2418,323 +2095,227 @@ void Task::modify (modType type, bool text_required /* = false */) //////////////////////////////////////////////////////////////////////////////// // Compare this task to another and summarize the differences for display, in // the future tense ("Foo will be set to .."). -std::string Task::diff (const Task& after) const -{ +std::string Task::diff(const Task& after) const { // Attributes are all there is, so figure the different attribute names // between this (before) and after. - std::vector beforeAtts; - for (auto& att : data) - beforeAtts.push_back (att.first); + std::vector beforeAtts; + for (auto& att : data) beforeAtts.push_back(att.first); - std::vector afterAtts; - for (auto& att : after.data) - afterAtts.push_back (att.first); + std::vector afterAtts; + for (auto& att : after.data) afterAtts.push_back(att.first); - std::vector beforeOnly; - std::vector afterOnly; - listDiff (beforeAtts, afterAtts, beforeOnly, afterOnly); + std::vector beforeOnly; + std::vector afterOnly; + listDiff(beforeAtts, afterAtts, beforeOnly, afterOnly); // Now start generating a description of the differences. std::stringstream out; - for (auto& name : beforeOnly) - { - if (isAnnotationAttr (name)) - { - out << " - " - << format ("Annotation {1} will be removed.", name) - << "\n"; - } - else if (isTagAttr (name)) - { - out << " - " - << format ("Tag {1} will be removed.", attr2Tag (name)) - << "\n"; - } - else if (isDepAttr (name)) - { - out << " - " - << format ("Depenency on {1} will be removed.", attr2Dep (name)) - << "\n"; - } - else if (name == "depends" || name == "tags") - { + for (auto& name : beforeOnly) { + if (isAnnotationAttr(name)) { + out << " - " << format("Annotation {1} will be removed.", name) << "\n"; + } else if (isTagAttr(name)) { + out << " - " << format("Tag {1} will be removed.", attr2Tag(name)) << "\n"; + } else if (isDepAttr(name)) { + out << " - " << format("Depenency on {1} will be removed.", attr2Dep(name)) << "\n"; + } else if (name == "depends" || name == "tags") { // do nothing for legacy attributes - } - else - { - out << " - " - << format ("{1} will be deleted.", Lexer::ucFirst (name)) - << "\n"; + } else { + out << " - " << format("{1} will be deleted.", Lexer::ucFirst(name)) << "\n"; } } - for (auto& name : afterOnly) - { - if (isAnnotationAttr (name)) - { - out << format ("Annotation of {1} will be added.\n", after.get (name)); - } - else if (isTagAttr (name)) - { - out << format ("Tag {1} will be added.\n", attr2Tag (name)); - } - else if (isDepAttr (name)) - { - out << format ("Dependency on {1} will be added.\n", attr2Dep (name)); - } - else if (name == "depends" || name == "tags") - { + for (auto& name : afterOnly) { + if (isAnnotationAttr(name)) { + out << format("Annotation of {1} will be added.\n", after.get(name)); + } else if (isTagAttr(name)) { + out << format("Tag {1} will be added.\n", attr2Tag(name)); + } else if (isDepAttr(name)) { + out << format("Dependency on {1} will be added.\n", attr2Dep(name)); + } else if (name == "depends" || name == "tags") { // do nothing for legacy attributes - } - else + } else out << " - " - << format ("{1} will be set to '{2}'.", - Lexer::ucFirst (name), - renderAttribute (name, after.get (name))) + << format("{1} will be set to '{2}'.", Lexer::ucFirst(name), + renderAttribute(name, after.get(name))) << "\n"; } - for (auto& name : beforeAtts) - { + for (auto& name : beforeAtts) { // Ignore UUID differences, and find values that changed, but are not also // in the beforeOnly and afterOnly lists, which have been handled above.. - if (name != "uuid" && - get (name) != after.get (name) && - std::find (beforeOnly.begin (), beforeOnly.end (), name) == beforeOnly.end () && - std::find (afterOnly.begin (), afterOnly.end (), name) == afterOnly.end ()) - { - if (name == "depends" || name == "tags") - { + if (name != "uuid" && get(name) != after.get(name) && + std::find(beforeOnly.begin(), beforeOnly.end(), name) == beforeOnly.end() && + std::find(afterOnly.begin(), afterOnly.end(), name) == afterOnly.end()) { + if (name == "depends" || name == "tags") { // do nothing for legacy attributes - } - else if (isTagAttr (name) || isDepAttr (name)) - { + } else if (isTagAttr(name) || isDepAttr(name)) { // ignore new attributes - } - else if (isAnnotationAttr (name)) - { - out << format ("Annotation will be changed to {1}.\n", after.get (name)); - } - else + } else if (isAnnotationAttr(name)) { + out << format("Annotation will be changed to {1}.\n", after.get(name)); + } else out << " - " - << format ("{1} will be changed from '{2}' to '{3}'.", - Lexer::ucFirst (name), - renderAttribute (name, get (name)), - renderAttribute (name, after.get (name))) + << format("{1} will be changed from '{2}' to '{3}'.", Lexer::ucFirst(name), + renderAttribute(name, get(name)), renderAttribute(name, after.get(name))) << "\n"; } } // Shouldn't just say nothing. - if (out.str ().length () == 0) - out << " - No changes will be made.\n"; + if (out.str().length() == 0) out << " - No changes will be made.\n"; - return out.str (); + return out.str(); } //////////////////////////////////////////////////////////////////////////////// // Similar to diff, but formatted for inclusion in the output of the info command -std::string Task::diffForInfo ( - const Task& after, - const std::string& dateformat, - long& last_timestamp, - const long current_timestamp) const -{ +std::string Task::diffForInfo(const Task& after, const std::string& dateformat, + long& last_timestamp, const long current_timestamp) const { // Attributes are all there is, so figure the different attribute names // between before and after. - std::vector beforeAtts; - for (auto& att : data) - beforeAtts.push_back (att.first); + std::vector beforeAtts; + for (auto& att : data) beforeAtts.push_back(att.first); - std::vector afterAtts; - for (auto& att : after.data) - afterAtts.push_back (att.first); + std::vector afterAtts; + for (auto& att : after.data) afterAtts.push_back(att.first); - std::vector beforeOnly; - std::vector afterOnly; - listDiff (beforeAtts, afterAtts, beforeOnly, afterOnly); + std::vector beforeOnly; + std::vector afterOnly; + listDiff(beforeAtts, afterAtts, beforeOnly, afterOnly); // Now start generating a description of the differences. std::stringstream out; - for (auto& name : beforeOnly) - { - if (isAnnotationAttr (name)) - { - out << format ("Annotation '{1}' deleted.\n", get (name)); - } - else if (isTagAttr (name)) - { - out << format ("Tag '{1}' deleted.\n", attr2Tag(name)); - } - else if (isDepAttr (name)) - { - out << format ("Dependency on '{1}' deleted.\n", attr2Dep(name)); - } - else if (name == "depends" || name == "tags") - { + for (auto& name : beforeOnly) { + if (isAnnotationAttr(name)) { + out << format("Annotation '{1}' deleted.\n", get(name)); + } else if (isTagAttr(name)) { + out << format("Tag '{1}' deleted.\n", attr2Tag(name)); + } else if (isDepAttr(name)) { + out << format("Dependency on '{1}' deleted.\n", attr2Dep(name)); + } else if (name == "depends" || name == "tags") { // do nothing for legacy attributes - } - else if (name == "start") - { - Datetime started (get ("start")); + } else if (name == "start") { + Datetime started(get("start")); Datetime stopped; - if (after.has ("end")) + if (after.has("end")) // Task was marked as finished, use end time - stopped = Datetime (after.get ("end")); + stopped = Datetime(after.get("end")); else // Start attribute was removed, use modification time - stopped = Datetime (current_timestamp); + stopped = Datetime(current_timestamp); - out << format ("{1} deleted (duration: {2}).", - Lexer::ucFirst (name), - Duration (stopped - started).format ()) + out << format("{1} deleted (duration: {2}).", Lexer::ucFirst(name), + Duration(stopped - started).format()) << "\n"; - } - else - { - out << format ("{1} deleted.\n", Lexer::ucFirst (name)); + } else { + out << format("{1} deleted.\n", Lexer::ucFirst(name)); } } - for (auto& name : afterOnly) - { - if (isAnnotationAttr (name)) - { - out << format ("Annotation of '{1}' added.\n", after.get (name)); - } - else if (isTagAttr (name)) - { - out << format ("Tag '{1}' added.\n", attr2Tag (name)); - } - else if (isDepAttr (name)) - { - out << format ("Dependency on '{1}' added.\n", attr2Dep (name)); - } - else if (name == "depends" || name == "tags") - { + for (auto& name : afterOnly) { + if (isAnnotationAttr(name)) { + out << format("Annotation of '{1}' added.\n", after.get(name)); + } else if (isTagAttr(name)) { + out << format("Tag '{1}' added.\n", attr2Tag(name)); + } else if (isDepAttr(name)) { + out << format("Dependency on '{1}' added.\n", attr2Dep(name)); + } else if (name == "depends" || name == "tags") { // do nothing for legacy attributes - } - else - { - if (name == "start") - last_timestamp = current_timestamp; + } else { + if (name == "start") last_timestamp = current_timestamp; - out << format ("{1} set to '{2}'.", - Lexer::ucFirst (name), - renderAttribute (name, after.get (name), dateformat)) + out << format("{1} set to '{2}'.", Lexer::ucFirst(name), + renderAttribute(name, after.get(name), dateformat)) << "\n"; } } for (auto& name : beforeAtts) - if (name != "uuid" && - name != "modified" && - get (name) != after.get (name) && - get (name) != "" && - after.get (name) != "") - { - if (name == "depends" || name == "tags") - { + if (name != "uuid" && name != "modified" && get(name) != after.get(name) && get(name) != "" && + after.get(name) != "") { + if (name == "depends" || name == "tags") { // do nothing for legacy attributes - } - else if (isTagAttr (name) || isDepAttr (name)) - { + } else if (isTagAttr(name) || isDepAttr(name)) { // ignore new attributes - } - else if (isAnnotationAttr (name)) - { - out << format ("Annotation changed to '{1}'.\n", after.get (name)); - } - else - out << format ("{1} changed from '{2}' to '{3}'.", - Lexer::ucFirst (name), - renderAttribute (name, get (name), dateformat), - renderAttribute (name, after.get (name), dateformat)) + } else if (isAnnotationAttr(name)) { + out << format("Annotation changed to '{1}'.\n", after.get(name)); + } else + out << format("{1} changed from '{2}' to '{3}'.", Lexer::ucFirst(name), + renderAttribute(name, get(name), dateformat), + renderAttribute(name, after.get(name), dateformat)) << "\n"; } // Shouldn't just say nothing. - if (out.str ().length () == 0) - out << "No changes made.\n"; + if (out.str().length() == 0) out << "No changes made.\n"; - return out.str (); + return out.str(); } //////////////////////////////////////////////////////////////////////////////// // Similar to diff, but formatted as a side-by-side table for an Undo preview -Table Task::diffForUndoSide ( - const Task& after) const -{ +Table Task::diffForUndoSide(const Task& after) const { // Set the colors. - Color color_red (Context::getContext ().color () ? Context::getContext ().config.get ("color.undo.before") : ""); - Color color_green (Context::getContext ().color () ? Context::getContext ().config.get ("color.undo.after") : ""); + Color color_red( + Context::getContext().color() ? Context::getContext().config.get("color.undo.before") : ""); + Color color_green( + Context::getContext().color() ? Context::getContext().config.get("color.undo.after") : ""); // Attributes are all there is, so figure the different attribute names // between before and after. Table view; - view.width (Context::getContext ().getWidth ()); - view.intraPadding (2); - view.add (""); - view.add ("Prior Values"); - view.add ("Current Values"); - setHeaderUnderline (view); + view.width(Context::getContext().getWidth()); + view.intraPadding(2); + view.add(""); + view.add("Prior Values"); + view.add("Current Values"); + setHeaderUnderline(view); - if (!is_empty ()) - { - const Task &before = *this; + if (!is_empty()) { + const Task& before = *this; - std::vector beforeAtts; - for (auto& att : before.data) - beforeAtts.push_back (att.first); + std::vector beforeAtts; + for (auto& att : before.data) beforeAtts.push_back(att.first); - std::vector afterAtts; - for (auto& att : after.data) - afterAtts.push_back (att.first); + std::vector afterAtts; + for (auto& att : after.data) afterAtts.push_back(att.first); - std::vector beforeOnly; - std::vector afterOnly; - listDiff (beforeAtts, afterAtts, beforeOnly, afterOnly); + std::vector beforeOnly; + std::vector afterOnly; + listDiff(beforeAtts, afterAtts, beforeOnly, afterOnly); int row; - for (auto& name : beforeOnly) - { - row = view.addRow (); - view.set (row, 0, name); - view.set (row, 1, renderAttribute (name, before.get (name)), color_red); + for (auto& name : beforeOnly) { + row = view.addRow(); + view.set(row, 0, name); + view.set(row, 1, renderAttribute(name, before.get(name)), color_red); } - for (auto& att : before.data) - { - std::string priorValue = before.get (att.first); - std::string currentValue = after.get (att.first); + for (auto& att : before.data) { + std::string priorValue = before.get(att.first); + std::string currentValue = after.get(att.first); - if (currentValue != "") - { - row = view.addRow (); - view.set (row, 0, att.first); - view.set (row, 1, renderAttribute (att.first, priorValue), - (priorValue != currentValue ? color_red : Color ())); - view.set (row, 2, renderAttribute (att.first, currentValue), - (priorValue != currentValue ? color_green : Color ())); + if (currentValue != "") { + row = view.addRow(); + view.set(row, 0, att.first); + view.set(row, 1, renderAttribute(att.first, priorValue), + (priorValue != currentValue ? color_red : Color())); + view.set(row, 2, renderAttribute(att.first, currentValue), + (priorValue != currentValue ? color_green : Color())); } } - for (auto& name : afterOnly) - { - row = view.addRow (); - view.set (row, 0, name); - view.set (row, 2, renderAttribute (name, after.get (name)), color_green); + for (auto& name : afterOnly) { + row = view.addRow(); + view.set(row, 0, name); + view.set(row, 2, renderAttribute(name, after.get(name)), color_green); } - } - else - { + } else { int row; - for (auto& att : after.data) - { - row = view.addRow (); - view.set (row, 0, att.first); - view.set (row, 2, renderAttribute (att.first, after.get (att.first)), color_green); + for (auto& att : after.data) { + row = view.addRow(); + view.set(row, 0, att.first); + view.set(row, 2, renderAttribute(att.first, after.get(att.first)), color_green); } } @@ -2743,10 +2324,7 @@ Table Task::diffForUndoSide ( //////////////////////////////////////////////////////////////////////////////// // Similar to diff, but formatted as a diff for an Undo preview -Table Task::diffForUndoPatch ( - const Task& after, - const Datetime& lastChange) const -{ +Table Task::diffForUndoPatch(const Task& after, const Datetime& lastChange) const { // This style looks like this: // --- before 2009-07-04 00:00:25.000000000 +0200 // +++ after 2009-07-04 00:00:45.000000000 +0200 @@ -2762,62 +2340,60 @@ Table Task::diffForUndoPatch ( // // Set the colors. - Color color_red (Context::getContext ().color () ? Context::getContext ().config.get ("color.undo.before") : ""); - Color color_green (Context::getContext ().color () ? Context::getContext ().config.get ("color.undo.after") : ""); + Color color_red( + Context::getContext().color() ? Context::getContext().config.get("color.undo.before") : ""); + Color color_green( + Context::getContext().color() ? Context::getContext().config.get("color.undo.after") : ""); - const Task &before = *this; + const Task& before = *this; // Generate table header. Table view; - view.width (Context::getContext ().getWidth ()); - view.intraPadding (2); - view.add (""); - view.add (""); + view.width(Context::getContext().getWidth()); + view.intraPadding(2); + view.add(""); + view.add(""); - int row = view.addRow (); - view.set (row, 0, "--- previous state", color_red); - view.set (row, 1, "Undo will restore this state", color_red); + int row = view.addRow(); + view.set(row, 0, "--- previous state", color_red); + view.set(row, 1, "Undo will restore this state", color_red); - row = view.addRow (); - view.set (row, 0, "+++ current state ", color_green); - view.set (row, 1, format ("Change made {1}", - lastChange.toString (Context::getContext ().config.get ("dateformat"))), - color_green); + row = view.addRow(); + view.set(row, 0, "+++ current state ", color_green); + view.set(row, 1, + format("Change made {1}", + lastChange.toString(Context::getContext().config.get("dateformat"))), + color_green); - view.addRow (); + view.addRow(); // Add rows to table showing diffs. - std::vector all = Context::getContext ().getColumns (); + std::vector all = Context::getContext().getColumns(); // Now factor in the annotation attributes. for (auto& it : before.data) - if (it.first.substr (0, 11) == "annotation_") - all.push_back (it.first); + if (it.first.substr(0, 11) == "annotation_") all.push_back(it.first); for (auto& it : after.data) - if (it.first.substr (0, 11) == "annotation_") - all.push_back (it.first); + if (it.first.substr(0, 11) == "annotation_") all.push_back(it.first); // Now render all the attributes. - std::sort (all.begin (), all.end ()); + std::sort(all.begin(), all.end()); std::string before_att; std::string after_att; std::string last_att; - for (auto& a : all) - { + for (auto& a : all) { if (a != last_att) // Skip duplicates. { last_att = a; - before_att = before.get (a); - after_att = after.get (a); + before_att = before.get(a); + after_att = after.get(a); // Don't report different uuid. // Show nothing if values are the unchanged. - if (a == "uuid" || - before_att == after_att) - { + if (a == "uuid" || before_att == after_att) { // Show nothing - no point displaying that which did not change. // row = view.addRow (); @@ -2826,37 +2402,34 @@ Table Task::diffForUndoPatch ( } // Attribute deleted. - else if (before_att != "" && after_att == "") - { - row = view.addRow (); - view.set (row, 0, '-' + a + ':', color_red); - view.set (row, 1, before_att, color_red); + else if (before_att != "" && after_att == "") { + row = view.addRow(); + view.set(row, 0, '-' + a + ':', color_red); + view.set(row, 1, before_att, color_red); - row = view.addRow (); - view.set (row, 0, '+' + a + ':', color_green); + row = view.addRow(); + view.set(row, 0, '+' + a + ':', color_green); } // Attribute added. - else if (before_att == "" && after_att != "") - { - row = view.addRow (); - view.set (row, 0, '-' + a + ':', color_red); + else if (before_att == "" && after_att != "") { + row = view.addRow(); + view.set(row, 0, '-' + a + ':', color_red); - row = view.addRow (); - view.set (row, 0, '+' + a + ':', color_green); - view.set (row, 1, after_att, color_green); + row = view.addRow(); + view.set(row, 0, '+' + a + ':', color_green); + view.set(row, 1, after_att, color_green); } // Attribute changed. - else - { - row = view.addRow (); - view.set (row, 0, '-' + a + ':', color_red); - view.set (row, 1, before_att, color_red); + else { + row = view.addRow(); + view.set(row, 0, '-' + a + ':', color_red); + view.set(row, 1, before_att, color_red); - row = view.addRow (); - view.set (row, 0, '+' + a + ':', color_green); - view.set (row, 1, after_att, color_green); + row = view.addRow(); + view.set(row, 0, '+' + a + ':', color_green); + view.set(row, 1, after_att, color_green); } } } diff --git a/src/Task.h b/src/Task.h index 3f4e16e16..28acb5c08 100644 --- a/src/Task.h +++ b/src/Task.h @@ -27,27 +27,27 @@ #ifndef INCLUDED_TASK #define INCLUDED_TASK -#include -#include -#include -#include -#include +#include #include #include -#include +#include #include +#include -class Task -{ -public: +#include +#include +#include + +class Task { + public: static std::string defaultProject; static std::string defaultDue; static std::string defaultScheduled; static bool searchCaseSensitive; static bool regex; - static std::map attributes; // name -> type - static std::map coefficients; - static std::map > customOrder; + static std::map attributes; // name -> type + static std::map coefficients; + static std::map> customOrder; static float urgencyProjectCoefficient; static float urgencyActiveCoefficient; static float urgencyScheduledCoefficient; @@ -60,159 +60,159 @@ public: static float urgencyAgeCoefficient; static float urgencyAgeMax; -public: - Task () = default; - bool operator== (const Task&); - bool operator!= (const Task&); - Task (const std::string&); - Task (const json::object*); - Task (tc::Task); + public: + Task() = default; + bool operator==(const Task&); + bool operator!=(const Task&); + Task(const std::string&); + Task(const json::object*); + Task(tc::Task); - void parse (const std::string&); - std::string composeJSON (bool decorate = false) const; + void parse(const std::string&); + std::string composeJSON(bool decorate = false) const; // Status values. - enum status {pending, completed, deleted, recurring, waiting}; + enum status { pending, completed, deleted, recurring, waiting }; // Date state values. - enum dateState {dateNotDue, dateAfterToday, dateLaterToday, dateEarlierToday, dateBeforeToday}; + enum dateState { dateNotDue, dateAfterToday, dateLaterToday, dateEarlierToday, dateBeforeToday }; // Public data. - int id {0}; - float urgency_value {0.0}; - bool recalc_urgency {true}; - bool is_blocked {false}; - bool is_blocking {false}; - int annotation_count {0}; + int id{0}; + float urgency_value{0.0}; + bool recalc_urgency{true}; + bool is_blocked{false}; + bool is_blocking{false}; + int annotation_count{0}; // Series of helper functions. - static status textToStatus (const std::string&); - static std::string statusToText (status); - static tc::Status status2tc (const Task::status); - static Task::status tc2status (const tc::Status); + static status textToStatus(const std::string&); + static std::string statusToText(status); + static tc::Status status2tc(const Task::status); + static Task::status tc2status(const tc::Status); - void setAsNow (const std::string&); - bool has (const std::string&) const; - std::vector all () const; - const std::string identifier (bool shortened = false) const; - const std::string get (const std::string&) const; - const std::string& get_ref (const std::string&) const; - int get_int (const std::string&) const; - unsigned long get_ulong (const std::string&) const; - float get_float (const std::string&) const; - time_t get_date (const std::string&) const; - void set (const std::string&, const std::string&); - void set (const std::string&, long long); - void remove (const std::string&); + void setAsNow(const std::string&); + bool has(const std::string&) const; + std::vector all() const; + const std::string identifier(bool shortened = false) const; + const std::string get(const std::string&) const; + const std::string& get_ref(const std::string&) const; + int get_int(const std::string&) const; + unsigned long get_ulong(const std::string&) const; + float get_float(const std::string&) const; + time_t get_date(const std::string&) const; + void set(const std::string&, const std::string&); + void set(const std::string&, long long); + void remove(const std::string&); - bool is_empty () const; + bool is_empty() const; #ifdef PRODUCT_TASKWARRIOR - bool is_ready () const; - bool is_due () const; - bool is_dueyesterday () const; - bool is_duetoday () const; - bool is_duetomorrow () const; - bool is_dueweek () const; - bool is_duemonth () const; - bool is_duequarter () const; - bool is_dueyear () const; - bool is_overdue () const; - bool is_udaPresent () const; - bool is_orphanPresent () const; + bool is_ready() const; + bool is_due() const; + bool is_dueyesterday() const; + bool is_duetoday() const; + bool is_duetomorrow() const; + bool is_dueweek() const; + bool is_duemonth() const; + bool is_duequarter() const; + bool is_dueyear() const; + bool is_overdue() const; + bool is_udaPresent() const; + bool is_orphanPresent() const; - static bool isTagAttr (const std::string&); - static bool isDepAttr (const std::string&); - static bool isAnnotationAttr (const std::string&); + static bool isTagAttr(const std::string&); + static bool isDepAttr(const std::string&); + static bool isAnnotationAttr(const std::string&); #endif - bool is_waiting () const; + bool is_waiting() const; - status getStatus () const; - void setStatus (status); + status getStatus() const; + void setStatus(status); #ifdef PRODUCT_TASKWARRIOR - dateState getDateState (const std::string&) const; + dateState getDateState(const std::string&) const; #endif - int getTagCount () const; - bool hasTag (const std::string&) const; - void addTag (const std::string&); - void setTags (const std::vector &); - std::vector getTags () const; - void removeTag (const std::string&); + int getTagCount() const; + bool hasTag(const std::string&) const; + void addTag(const std::string&); + void setTags(const std::vector&); + std::vector getTags() const; + void removeTag(const std::string&); - int getAnnotationCount () const; - bool hasAnnotations () const; - std::map getAnnotations () const; - void setAnnotations (const std::map &); - void addAnnotation (const std::string&); - void removeAnnotations (); + int getAnnotationCount() const; + bool hasAnnotations() const; + std::map getAnnotations() const; + void setAnnotations(const std::map&); + void addAnnotation(const std::string&); + void removeAnnotations(); #ifdef PRODUCT_TASKWARRIOR - void addDependency (int); + void addDependency(int); #endif - void addDependency (const std::string&); + void addDependency(const std::string&); #ifdef PRODUCT_TASKWARRIOR - void removeDependency (int); - void removeDependency (const std::string&); - bool hasDependency (const std::string&) const; - std::vector getDependencyIDs () const; - std::vector getDependencyUUIDs () const; - std::vector getBlockedTasks () const; - std::vector getDependencyTasks () const; + void removeDependency(int); + void removeDependency(const std::string&); + bool hasDependency(const std::string&) const; + std::vector getDependencyIDs() const; + std::vector getDependencyUUIDs() const; + std::vector getBlockedTasks() const; + std::vector getDependencyTasks() const; - std::vector getUDAOrphans () const; + std::vector getUDAOrphans() const; - void substitute (const std::string&, const std::string&, const std::string&); + void substitute(const std::string&, const std::string&, const std::string&); #endif - void validate (bool applyDefault = true); + void validate(bool applyDefault = true); - float urgency_c () const; - float urgency (); + float urgency_c() const; + float urgency(); #ifdef PRODUCT_TASKWARRIOR - enum modType {modReplace, modPrepend, modAppend, modAnnotate}; - void modify (modType, bool text_required = false); + enum modType { modReplace, modPrepend, modAppend, modAnnotate }; + void modify(modType, bool text_required = false); #endif - std::string diff (const Task& after) const; - std::string diffForInfo (const Task& after, const std::string& dateformat, long& last_timestamp, const long current_timestamp) const; - Table diffForUndoSide (const Task& after) const; - Table diffForUndoPatch (const Task& after, const Datetime& lastChange) const; + std::string diff(const Task& after) const; + std::string diffForInfo(const Task& after, const std::string& dateformat, long& last_timestamp, + const long current_timestamp) const; + Table diffForUndoSide(const Task& after) const; + Table diffForUndoPatch(const Task& after, const Datetime& lastChange) const; + private: + int determineVersion(const std::string&); + void parseJSON(const std::string&); + void parseJSON(const json::object*); + void parseTC(const tc::Task&); + void parseLegacy(const std::string&); + void validate_before(const std::string&, const std::string&); + const std::string encode(const std::string&) const; + const std::string decode(const std::string&) const; + const std::string tag2Attr(const std::string&) const; + const std::string attr2Tag(const std::string&) const; + const std::string dep2Attr(const std::string&) const; + const std::string attr2Dep(const std::string&) const; + void fixDependsAttribute(); + void fixTagsAttribute(); -private: - int determineVersion (const std::string&); - void parseJSON (const std::string&); - void parseJSON (const json::object*); - void parseTC (const tc::Task&); - void parseLegacy (const std::string&); - void validate_before (const std::string&, const std::string&); - const std::string encode (const std::string&) const; - const std::string decode (const std::string&) const; - const std::string tag2Attr (const std::string&) const; - const std::string attr2Tag (const std::string&) const; - const std::string dep2Attr (const std::string&) const; - const std::string attr2Dep (const std::string&) const; - void fixDependsAttribute (); - void fixTagsAttribute (); + protected: + std::map data{}; -protected: - std::map data {}; - -public: - float urgency_project () const; - float urgency_active () const; - float urgency_scheduled () const; - float urgency_waiting () const; - float urgency_blocked () const; - float urgency_inherit () const; - float urgency_annotations () const; - float urgency_tags () const; - float urgency_due () const; - float urgency_blocking () const; - float urgency_age () const; + public: + float urgency_project() const; + float urgency_active() const; + float urgency_scheduled() const; + float urgency_waiting() const; + float urgency_blocked() const; + float urgency_inherit() const; + float urgency_annotations() const; + float urgency_tags() const; + float urgency_due() const; + float urgency_blocking() const; + float urgency_age() const; }; #endif diff --git a/src/Variant.cpp b/src/Variant.cpp index 3d34f7327..a5b68f172 100644 --- a/src/Variant.cpp +++ b/src/Variant.cpp @@ -27,927 +27,944 @@ #include // cmake.h include header must come first -#include -#include -#include -#include -#include -#include #include #include #include #include +#include +#include #include +#include +#include + +#include +#include // These are all error messages generated by the expression evaluator, and are // mostly concerned with how various operators interact with the different // data types. -#define STRING_VARIANT_TIME_T "Cannot instantiate this type with a time_t value." -#define STRING_VARIANT_EXP_BOOL "Cannot exponentiate Booleans" -#define STRING_VARIANT_EXP_NON_INT "Cannot exponentiate to a non-integer power" -#define STRING_VARIANT_EXP_STRING "Cannot exponentiate strings" -#define STRING_VARIANT_EXP_DATE "Cannot exponentiate dates" -#define STRING_VARIANT_EXP_DURATION "Cannot exponentiate durations" -#define STRING_VARIANT_SUB_BOOL "Cannot subtract from a Boolean value" -#define STRING_VARIANT_SUB_STRING "Cannot subtract strings" -#define STRING_VARIANT_SUB_DATE "Cannot subtract a date" -#define STRING_VARIANT_ADD_BOOL "Cannot add two Boolean values" -#define STRING_VARIANT_ADD_DATE "Cannot add two date values" -#define STRING_VARIANT_MUL_BOOL "Cannot multiply Boolean values" -#define STRING_VARIANT_MUL_DATE "Cannot multiply date values" -#define STRING_VARIANT_MUL_REAL_STR "Cannot multiply real numbers by strings" -#define STRING_VARIANT_MUL_STR_REAL "Cannot multiply strings by real numbers" -#define STRING_VARIANT_MUL_STR_STR "Cannot multiply strings by strings" -#define STRING_VARIANT_MUL_STR_DATE "Cannot multiply strings by dates" -#define STRING_VARIANT_MUL_STR_DUR "Cannot multiply strings by durations" -#define STRING_VARIANT_MUL_DUR_STR "Cannot multiply durations by strings" -#define STRING_VARIANT_MUL_DUR_DATE "Cannot multiply durations by dates" -#define STRING_VARIANT_MUL_DUR_DUR "Cannot multiply durations by durations" -#define STRING_VARIANT_DIV_BOOL "Cannot divide Boolean values" -#define STRING_VARIANT_DIV_INT_BOOL "Cannot divide integers by Boolean values" -#define STRING_VARIANT_DIV_ZERO "Cannot divide by zero" -#define STRING_VARIANT_DIV_INT_STR "Cannot divide integer by string" -#define STRING_VARIANT_DIV_INT_DATE "Cannot divide integer by date values" +#define STRING_VARIANT_TIME_T "Cannot instantiate this type with a time_t value." +#define STRING_VARIANT_EXP_BOOL "Cannot exponentiate Booleans" +#define STRING_VARIANT_EXP_NON_INT "Cannot exponentiate to a non-integer power" +#define STRING_VARIANT_EXP_STRING "Cannot exponentiate strings" +#define STRING_VARIANT_EXP_DATE "Cannot exponentiate dates" +#define STRING_VARIANT_EXP_DURATION "Cannot exponentiate durations" +#define STRING_VARIANT_SUB_BOOL "Cannot subtract from a Boolean value" +#define STRING_VARIANT_SUB_STRING "Cannot subtract strings" +#define STRING_VARIANT_SUB_DATE "Cannot subtract a date" +#define STRING_VARIANT_ADD_BOOL "Cannot add two Boolean values" +#define STRING_VARIANT_ADD_DATE "Cannot add two date values" +#define STRING_VARIANT_MUL_BOOL "Cannot multiply Boolean values" +#define STRING_VARIANT_MUL_DATE "Cannot multiply date values" +#define STRING_VARIANT_MUL_REAL_STR "Cannot multiply real numbers by strings" +#define STRING_VARIANT_MUL_STR_REAL "Cannot multiply strings by real numbers" +#define STRING_VARIANT_MUL_STR_STR "Cannot multiply strings by strings" +#define STRING_VARIANT_MUL_STR_DATE "Cannot multiply strings by dates" +#define STRING_VARIANT_MUL_STR_DUR "Cannot multiply strings by durations" +#define STRING_VARIANT_MUL_DUR_STR "Cannot multiply durations by strings" +#define STRING_VARIANT_MUL_DUR_DATE "Cannot multiply durations by dates" +#define STRING_VARIANT_MUL_DUR_DUR "Cannot multiply durations by durations" +#define STRING_VARIANT_DIV_BOOL "Cannot divide Boolean values" +#define STRING_VARIANT_DIV_INT_BOOL "Cannot divide integers by Boolean values" +#define STRING_VARIANT_DIV_ZERO "Cannot divide by zero" +#define STRING_VARIANT_DIV_INT_STR "Cannot divide integer by string" +#define STRING_VARIANT_DIV_INT_DATE "Cannot divide integer by date values" #define STRING_VARIANT_DIV_REAL_BOOL "Cannot divide real by Boolean" -#define STRING_VARIANT_DIV_REAL_STR "Cannot divide real numbers by strings" +#define STRING_VARIANT_DIV_REAL_STR "Cannot divide real numbers by strings" #define STRING_VARIANT_DIV_REAL_DATE "Cannot divide real numbers by dates" -#define STRING_VARIANT_DIV_DUR_BOOL "Cannot divide duration by Boolean" -#define STRING_VARIANT_DIV_DUR_STR "Cannot divide durations by strings" -#define STRING_VARIANT_DIV_DUR_DATE "Cannot divide durations by dates" -#define STRING_VARIANT_DIV_DUR_DUR "Cannot divide durations by durations" -#define STRING_VARIANT_MOD_BOOL "Cannot modulo Booleans" -#define STRING_VARIANT_MOD_DATE "Cannot modulo date values" -#define STRING_VARIANT_MOD_DUR "Cannot modulo duration values" -#define STRING_VARIANT_MOD_INT_BOOL "Cannot modulo integer by Boolean" -#define STRING_VARIANT_MOD_INT_DATE "Cannot modulo integer by date values" -#define STRING_VARIANT_MOD_INT_DUR "Cannot modulo integer by duration values" -#define STRING_VARIANT_MOD_INT_STR "Cannot modulo integer by string" +#define STRING_VARIANT_DIV_DUR_BOOL "Cannot divide duration by Boolean" +#define STRING_VARIANT_DIV_DUR_STR "Cannot divide durations by strings" +#define STRING_VARIANT_DIV_DUR_DATE "Cannot divide durations by dates" +#define STRING_VARIANT_DIV_DUR_DUR "Cannot divide durations by durations" +#define STRING_VARIANT_MOD_BOOL "Cannot modulo Booleans" +#define STRING_VARIANT_MOD_DATE "Cannot modulo date values" +#define STRING_VARIANT_MOD_DUR "Cannot modulo duration values" +#define STRING_VARIANT_MOD_INT_BOOL "Cannot modulo integer by Boolean" +#define STRING_VARIANT_MOD_INT_DATE "Cannot modulo integer by date values" +#define STRING_VARIANT_MOD_INT_DUR "Cannot modulo integer by duration values" +#define STRING_VARIANT_MOD_INT_STR "Cannot modulo integer by string" #define STRING_VARIANT_MOD_REAL_BOOL "Cannot modulo real by Boolean" -#define STRING_VARIANT_MOD_REAL_DUR "Cannot modulo real by duration values" +#define STRING_VARIANT_MOD_REAL_DUR "Cannot modulo real by duration values" #define STRING_VARIANT_MOD_REAL_DATE "Cannot modulo real numbers by dates" -#define STRING_VARIANT_MOD_REAL_STR "Cannot modulo real numbers by strings" -#define STRING_VARIANT_MOD_STR "Cannot modulo string values" -#define STRING_VARIANT_MOD_ZERO "Cannot modulo zero" -#define STRING_VARIANT_SQRT_NEG "Cannot take the square root of a negative number." +#define STRING_VARIANT_MOD_REAL_STR "Cannot modulo real numbers by strings" +#define STRING_VARIANT_MOD_STR "Cannot modulo string values" +#define STRING_VARIANT_MOD_ZERO "Cannot modulo zero" +#define STRING_VARIANT_SQRT_NEG "Cannot take the square root of a negative number." std::string Variant::dateFormat = ""; bool Variant::searchCaseSensitive = true; bool Variant::searchUsingRegex = true; //////////////////////////////////////////////////////////////////////////////// -Variant::Variant (const Variant& other) -{ - _type = other._type; - _bool = other._bool; - _integer = other._integer; - _real = other._real; - _string = other._string; - _date = other._date; +Variant::Variant(const Variant& other) { + _type = other._type; + _bool = other._bool; + _integer = other._integer; + _real = other._real; + _string = other._string; + _date = other._date; _duration = other._duration; - _source = other._source; + _source = other._source; } //////////////////////////////////////////////////////////////////////////////// -Variant::Variant (const bool value) -: _type (Variant::type_boolean) -, _bool (value) -{ -} +Variant::Variant(const bool value) : _type(Variant::type_boolean), _bool(value) {} //////////////////////////////////////////////////////////////////////////////// -Variant::Variant (const int value) -: _type (Variant::type_integer) -, _integer (value) -{ -} +Variant::Variant(const int value) : _type(Variant::type_integer), _integer(value) {} //////////////////////////////////////////////////////////////////////////////// -Variant::Variant (const double value) -: _type (Variant::type_real) -, _real (value) -{ -} +Variant::Variant(const double value) : _type(Variant::type_real), _real(value) {} //////////////////////////////////////////////////////////////////////////////// -Variant::Variant (const std::string& value) -: _type (Variant::type_string) -, _string (value) -{ -} +Variant::Variant(const std::string& value) : _type(Variant::type_string), _string(value) {} //////////////////////////////////////////////////////////////////////////////// -Variant::Variant (const char* value) -: _type (Variant::type_string) -, _string (value) -{ -} +Variant::Variant(const char* value) : _type(Variant::type_string), _string(value) {} //////////////////////////////////////////////////////////////////////////////// -Variant::Variant (const time_t value, const enum type new_type) -: _type (new_type) -{ - switch (new_type) - { - case type_date: _date = value; break; - case type_duration: _duration = value; break; - default: - throw std::string (STRING_VARIANT_TIME_T); +Variant::Variant(const time_t value, const enum type new_type) : _type(new_type) { + switch (new_type) { + case type_date: + _date = value; + break; + case type_duration: + _duration = value; + break; + default: + throw std::string(STRING_VARIANT_TIME_T); } } //////////////////////////////////////////////////////////////////////////////// -void Variant::source (const std::string& input) -{ - _source = input; -} +void Variant::source(const std::string& input) { _source = input; } //////////////////////////////////////////////////////////////////////////////// -const std::string& Variant::source () const -{ - return _source; -} +const std::string& Variant::source() const { return _source; } //////////////////////////////////////////////////////////////////////////////// -Variant& Variant::operator= (const Variant& other) = default; +Variant& Variant::operator=(const Variant& other) = default; //////////////////////////////////////////////////////////////////////////////// -bool Variant::operator&& (const Variant& other) const -{ - Variant left (*this); - Variant right (other); +bool Variant::operator&&(const Variant& other) const { + Variant left(*this); + Variant right(other); - if (left._type == type_string) - Lexer::dequote (left._string); + if (left._type == type_string) Lexer::dequote(left._string); - if (right._type == type_string) - Lexer::dequote (right._string); + if (right._type == type_string) Lexer::dequote(right._string); - left.cast (type_boolean); - right.cast (type_boolean); + left.cast(type_boolean); + right.cast(type_boolean); return left._bool && right._bool; } //////////////////////////////////////////////////////////////////////////////// -bool Variant::operator|| (const Variant& other) const -{ - Variant left (*this); - Variant right (other); +bool Variant::operator||(const Variant& other) const { + Variant left(*this); + Variant right(other); - if (left._type == type_string) - Lexer::dequote (left._string); + if (left._type == type_string) Lexer::dequote(left._string); - if (right._type == type_string) - Lexer::dequote (right._string); + if (right._type == type_string) Lexer::dequote(right._string); - left.cast (type_boolean); - right.cast (type_boolean); + left.cast(type_boolean); + right.cast(type_boolean); return left._bool || right._bool; } //////////////////////////////////////////////////////////////////////////////// -bool Variant::operator_xor (const Variant& other) const -{ - Variant left (*this); - Variant right (other); +bool Variant::operator_xor(const Variant& other) const { + Variant left(*this); + Variant right(other); - if (left._type == type_string) - Lexer::dequote (left._string); + if (left._type == type_string) Lexer::dequote(left._string); - if (right._type == type_string) - Lexer::dequote (right._string); + if (right._type == type_string) Lexer::dequote(right._string); - left.cast (type_boolean); - right.cast (type_boolean); + left.cast(type_boolean); + right.cast(type_boolean); - return (left._bool && !right._bool) || - (!left._bool && right._bool); + return (left._bool && !right._bool) || (!left._bool && right._bool); } //////////////////////////////////////////////////////////////////////////////// -bool Variant::operator< (const Variant& other) const -{ - Variant left (*this); - Variant right (other); +bool Variant::operator<(const Variant& other) const { + Variant left(*this); + Variant right(other); - if (left._type == type_string) - Lexer::dequote (left._string); + if (left._type == type_string) Lexer::dequote(left._string); - if (right._type == type_string) - Lexer::dequote (right._string); + if (right._type == type_string) Lexer::dequote(right._string); - switch (left._type) - { - case type_boolean: - switch (right._type) - { - case type_boolean: return !left._bool && right._bool; - case type_integer: left.cast (type_integer); return left._integer < right._integer; - case type_real: left.cast (type_real); return left._real < right._real; - case type_string: left.cast (type_string); return left._string < right._string; - case type_date: left.cast (type_date); return left._date < right._date; - case type_duration: left.cast (type_duration); return left._duration < right._duration; - } - break; - - case type_integer: - switch (right._type) - { - case type_boolean: right.cast (type_integer); return left._integer < right._integer; - case type_integer: return left._integer < right._integer; - case type_real: left.cast (type_real); return left._real < right._real; - case type_string: left.cast (type_string); return left._string < right._string; - case type_date: left.cast (type_date); return left._date < right._date; - case type_duration: left.cast (type_duration); return left._duration < right._duration; - } - break; - - case type_real: - switch (right._type) - { - case type_boolean: right.cast (type_real); return left._real < right._real; - case type_integer: right.cast (type_real); return left._real < right._real; - case type_real: return left._real < right._real; - case type_string: left.cast (type_string); return left._string < right._string; - case type_date: left.cast (type_date); return left._date < right._date; - case type_duration: left.cast (type_duration); return left._duration < right._duration; - } - break; - - case type_string: - switch (right._type) - { + switch (left._type) { case type_boolean: - case type_integer: - case type_real: - right.cast (type_string); - return left._string < right._string; - - case type_string: - { - if (left._string == right._string) - return false; - - auto order = Task::customOrder.find (left.source ()); - if (order != Task::customOrder.end ()) - { - // Guaranteed to be found, because of ColUDA::validate (). - auto posLeft = std::find (order->second.begin (), order->second.end (), left._string); - auto posRight = std::find (order->second.begin (), order->second.end (), right._string); - return posLeft < posRight; - } - else - { - if (left.trivial () || right.trivial ()) - return false; - + switch (right._type) { + case type_boolean: + return !left._bool && right._bool; + case type_integer: + left.cast(type_integer); + return left._integer < right._integer; + case type_real: + left.cast(type_real); + return left._real < right._real; + case type_string: + left.cast(type_string); return left._string < right._string; - } + case type_date: + left.cast(type_date); + return left._date < right._date; + case type_duration: + left.cast(type_duration); + return left._duration < right._duration; } + break; - case type_date: - if (left.trivial () || right.trivial ()) - return false; - - left.cast (type_date); - return left._date < right._date; - - case type_duration: - if (left.trivial () || right.trivial ()) - return false; - - left.cast (type_duration); - return left._duration < right._duration; - } - break; - - case type_date: - switch (right._type) - { - case type_boolean: case type_integer: + switch (right._type) { + case type_boolean: + right.cast(type_integer); + return left._integer < right._integer; + case type_integer: + return left._integer < right._integer; + case type_real: + left.cast(type_real); + return left._real < right._real; + case type_string: + left.cast(type_string); + return left._string < right._string; + case type_date: + left.cast(type_date); + return left._date < right._date; + case type_duration: + left.cast(type_duration); + return left._duration < right._duration; + } + break; + case type_real: + switch (right._type) { + case type_boolean: + right.cast(type_real); + return left._real < right._real; + case type_integer: + right.cast(type_real); + return left._real < right._real; + case type_real: + return left._real < right._real; + case type_string: + left.cast(type_string); + return left._string < right._string; + case type_date: + left.cast(type_date); + return left._date < right._date; + case type_duration: + left.cast(type_duration); + return left._duration < right._duration; + } + break; + case type_string: + switch (right._type) { + case type_boolean: + case type_integer: + case type_real: + right.cast(type_string); + return left._string < right._string; + + case type_string: { + if (left._string == right._string) return false; + + auto order = Task::customOrder.find(left.source()); + if (order != Task::customOrder.end()) { + // Guaranteed to be found, because of ColUDA::validate (). + auto posLeft = std::find(order->second.begin(), order->second.end(), left._string); + auto posRight = std::find(order->second.begin(), order->second.end(), right._string); + return posLeft < posRight; + } else { + if (left.trivial() || right.trivial()) return false; + + return left._string < right._string; + } + } + + case type_date: + if (left.trivial() || right.trivial()) return false; + + left.cast(type_date); + return left._date < right._date; + + case type_duration: + if (left.trivial() || right.trivial()) return false; + + left.cast(type_duration); + return left._duration < right._duration; + } + break; + case type_date: + switch (right._type) { + case type_boolean: + case type_integer: + case type_real: + case type_string: + case type_date: + case type_duration: + if (left.trivial() || right.trivial()) return false; + + right.cast(type_date); + return left._date < right._date; + } + break; + case type_duration: - if (left.trivial () || right.trivial ()) - return false; + switch (right._type) { + case type_boolean: + case type_integer: + case type_real: + case type_string: + case type_date: + case type_duration: + if (left.trivial() || right.trivial()) return false; - right.cast (type_date); - return left._date < right._date; - } - break; - - case type_duration: - switch (right._type) - { - case type_boolean: - case type_integer: - case type_real: - case type_string: - case type_date: - case type_duration: - if (left.trivial () || right.trivial ()) - return false; - - right.cast (type_duration); - return left._duration < right._duration; - } - break; + right.cast(type_duration); + return left._duration < right._duration; + } + break; } return false; } //////////////////////////////////////////////////////////////////////////////// -bool Variant::operator<= (const Variant& other) const -{ - Variant left (*this); - Variant right (other); +bool Variant::operator<=(const Variant& other) const { + Variant left(*this); + Variant right(other); - if (left._type == type_string) - Lexer::dequote (left._string); + if (left._type == type_string) Lexer::dequote(left._string); - if (right._type == type_string) - Lexer::dequote (right._string); + if (right._type == type_string) Lexer::dequote(right._string); - switch (left._type) - { - case type_boolean: - switch (right._type) - { - case type_boolean: return !left._bool || right._bool; - case type_integer: left.cast (type_integer); return left._integer <= right._integer; - case type_real: left.cast (type_real); return left._real <= right._real; - case type_string: left.cast (type_string); return left._string <= right._string; - case type_date: left.cast (type_date); return left._date <= right._date; - case type_duration: left.cast (type_duration); return left._duration <= right._duration; - } - break; - - case type_integer: - switch (right._type) - { - case type_boolean: right.cast (type_integer); return left._integer <= right._integer; - case type_integer: return left._integer <= right._integer; - case type_real: left.cast (type_real); return left._real <= right._real; - case type_string: left.cast (type_string); return left._string <= right._string; - case type_date: left.cast (type_date); return left._date <= right._date; - case type_duration: left.cast (type_duration); return left._duration <= right._duration; - } - break; - - case type_real: - switch (right._type) - { - case type_boolean: right.cast (type_real); return left._real <= right._real; - case type_integer: right.cast (type_real); return left._real <= right._real; - case type_real: return left._real <= right._real; - case type_string: left.cast (type_string); return left._string <= right._string; - case type_date: left.cast (type_date); return left._date <= right._date; - case type_duration: left.cast (type_duration); return left._duration <= right._duration; - } - break; - - case type_string: - switch (right._type) - { + switch (left._type) { case type_boolean: - case type_integer: - case type_real: - right.cast (type_string); - return left._string <= right._string; - - case type_string: - { - if (left._string == right._string) - return true; - - auto order = Task::customOrder.find (left.source ()); - if (order != Task::customOrder.end ()) - { - // Guaranteed to be found, because of ColUDA::validate (). - auto posLeft = std::find (order->second.begin (), order->second.end (), left._string); - auto posRight = std::find (order->second.begin (), order->second.end (), right._string); - return posLeft <= posRight; - } - else - { - if (left.trivial () || right.trivial ()) - return false; - + switch (right._type) { + case type_boolean: + return !left._bool || right._bool; + case type_integer: + left.cast(type_integer); + return left._integer <= right._integer; + case type_real: + left.cast(type_real); + return left._real <= right._real; + case type_string: + left.cast(type_string); return left._string <= right._string; - } + case type_date: + left.cast(type_date); + return left._date <= right._date; + case type_duration: + left.cast(type_duration); + return left._duration <= right._duration; } + break; - case type_date: - if (left.trivial () || right.trivial ()) - return false; - - left.cast (type_date); - return left._date <= right._date; - - case type_duration: - if (left.trivial () || right.trivial ()) - return false; - - left.cast (type_duration); - return left._duration <= right._duration; - } - break; - - case type_date: - switch (right._type) - { - case type_boolean: case type_integer: + switch (right._type) { + case type_boolean: + right.cast(type_integer); + return left._integer <= right._integer; + case type_integer: + return left._integer <= right._integer; + case type_real: + left.cast(type_real); + return left._real <= right._real; + case type_string: + left.cast(type_string); + return left._string <= right._string; + case type_date: + left.cast(type_date); + return left._date <= right._date; + case type_duration: + left.cast(type_duration); + return left._duration <= right._duration; + } + break; + case type_real: + switch (right._type) { + case type_boolean: + right.cast(type_real); + return left._real <= right._real; + case type_integer: + right.cast(type_real); + return left._real <= right._real; + case type_real: + return left._real <= right._real; + case type_string: + left.cast(type_string); + return left._string <= right._string; + case type_date: + left.cast(type_date); + return left._date <= right._date; + case type_duration: + left.cast(type_duration); + return left._duration <= right._duration; + } + break; + case type_string: + switch (right._type) { + case type_boolean: + case type_integer: + case type_real: + right.cast(type_string); + return left._string <= right._string; + + case type_string: { + if (left._string == right._string) return true; + + auto order = Task::customOrder.find(left.source()); + if (order != Task::customOrder.end()) { + // Guaranteed to be found, because of ColUDA::validate (). + auto posLeft = std::find(order->second.begin(), order->second.end(), left._string); + auto posRight = std::find(order->second.begin(), order->second.end(), right._string); + return posLeft <= posRight; + } else { + if (left.trivial() || right.trivial()) return false; + + return left._string <= right._string; + } + } + + case type_date: + if (left.trivial() || right.trivial()) return false; + + left.cast(type_date); + return left._date <= right._date; + + case type_duration: + if (left.trivial() || right.trivial()) return false; + + left.cast(type_duration); + return left._duration <= right._duration; + } + break; + case type_date: + switch (right._type) { + case type_boolean: + case type_integer: + case type_real: + case type_string: + case type_date: + case type_duration: + if (left.trivial() || right.trivial()) return false; + + right.cast(type_date); + return left._date <= right._date; + } + break; + case type_duration: - if (left.trivial () || right.trivial ()) - return false; + switch (right._type) { + case type_boolean: + case type_integer: + case type_real: + case type_string: + case type_date: + case type_duration: + if (left.trivial() || right.trivial()) return false; - right.cast (type_date); - return left._date <= right._date; - } - break; - - case type_duration: - switch (right._type) - { - case type_boolean: - case type_integer: - case type_real: - case type_string: - case type_date: - case type_duration: - if (left.trivial () || right.trivial ()) - return false; - - right.cast (type_duration); - return left._duration <= right._duration; - } - break; + right.cast(type_duration); + return left._duration <= right._duration; + } + break; } return false; } //////////////////////////////////////////////////////////////////////////////// -bool Variant::operator> (const Variant& other) const -{ - Variant left (*this); - Variant right (other); +bool Variant::operator>(const Variant& other) const { + Variant left(*this); + Variant right(other); - if (left._type == type_string) - Lexer::dequote (left._string); + if (left._type == type_string) Lexer::dequote(left._string); - if (right._type == type_string) - Lexer::dequote (right._string); + if (right._type == type_string) Lexer::dequote(right._string); - switch (left._type) - { - case type_boolean: - switch (right._type) - { - case type_boolean: return !left._bool && right._bool; - case type_integer: left.cast (type_integer); return left._integer > right._integer; - case type_real: left.cast (type_real); return left._real > right._real; - case type_string: left.cast (type_string); return left._string > right._string; - case type_date: left.cast (type_date); return left._date > right._date; - case type_duration: left.cast (type_duration); return left._duration > right._duration; - } - break; - - case type_integer: - switch (right._type) - { - case type_boolean: right.cast (type_integer); return left._integer > right._integer; - case type_integer: return left._integer > right._integer; - case type_real: left.cast (type_real); return left._real > right._real; - case type_string: left.cast (type_string); return left._string > right._string; - case type_date: left.cast (type_date); return left._date > right._date; - case type_duration: left.cast (type_duration); return left._duration > right._duration; - } - break; - - case type_real: - switch (right._type) - { - case type_boolean: right.cast (type_real); return left._real > right._real; - case type_integer: right.cast (type_real); return left._real > right._real; - case type_real: return left._real > right._real; - case type_string: left.cast (type_string); return left._string > right._string; - case type_date: left.cast (type_date); return left._date > right._date; - case type_duration: left.cast (type_duration); return left._duration > right._duration; - } - break; - - case type_string: - switch (right._type) - { + switch (left._type) { case type_boolean: - case type_integer: - case type_real: - right.cast (type_string); - return left._string > right._string; - - case type_string: - { - if (left._string == right._string) - return false; - - auto order = Task::customOrder.find (left.source ()); - if (order != Task::customOrder.end ()) - { - // Guaranteed to be found, because of ColUDA::validate (). - auto posLeft = std::find (order->second.begin (), order->second.end (), left._string); - auto posRight = std::find (order->second.begin (), order->second.end (), right._string); - return posLeft > posRight; - } - else - { - if (left.trivial () || right.trivial ()) - return false; - + switch (right._type) { + case type_boolean: + return !left._bool && right._bool; + case type_integer: + left.cast(type_integer); + return left._integer > right._integer; + case type_real: + left.cast(type_real); + return left._real > right._real; + case type_string: + left.cast(type_string); return left._string > right._string; - } + case type_date: + left.cast(type_date); + return left._date > right._date; + case type_duration: + left.cast(type_duration); + return left._duration > right._duration; } + break; - case type_date: - if (left.trivial () || right.trivial ()) - return false; - - left.cast (type_date); - return left._date > right._date; - - case type_duration: - if (left.trivial () || right.trivial ()) - return false; - - left.cast (type_duration); - return left._duration > right._duration; - } - break; - - case type_date: - switch (right._type) - { - case type_boolean: case type_integer: + switch (right._type) { + case type_boolean: + right.cast(type_integer); + return left._integer > right._integer; + case type_integer: + return left._integer > right._integer; + case type_real: + left.cast(type_real); + return left._real > right._real; + case type_string: + left.cast(type_string); + return left._string > right._string; + case type_date: + left.cast(type_date); + return left._date > right._date; + case type_duration: + left.cast(type_duration); + return left._duration > right._duration; + } + break; + case type_real: + switch (right._type) { + case type_boolean: + right.cast(type_real); + return left._real > right._real; + case type_integer: + right.cast(type_real); + return left._real > right._real; + case type_real: + return left._real > right._real; + case type_string: + left.cast(type_string); + return left._string > right._string; + case type_date: + left.cast(type_date); + return left._date > right._date; + case type_duration: + left.cast(type_duration); + return left._duration > right._duration; + } + break; + case type_string: + switch (right._type) { + case type_boolean: + case type_integer: + case type_real: + right.cast(type_string); + return left._string > right._string; + + case type_string: { + if (left._string == right._string) return false; + + auto order = Task::customOrder.find(left.source()); + if (order != Task::customOrder.end()) { + // Guaranteed to be found, because of ColUDA::validate (). + auto posLeft = std::find(order->second.begin(), order->second.end(), left._string); + auto posRight = std::find(order->second.begin(), order->second.end(), right._string); + return posLeft > posRight; + } else { + if (left.trivial() || right.trivial()) return false; + + return left._string > right._string; + } + } + + case type_date: + if (left.trivial() || right.trivial()) return false; + + left.cast(type_date); + return left._date > right._date; + + case type_duration: + if (left.trivial() || right.trivial()) return false; + + left.cast(type_duration); + return left._duration > right._duration; + } + break; + case type_date: + switch (right._type) { + case type_boolean: + case type_integer: + case type_real: + case type_string: + case type_date: + case type_duration: + if (left.trivial() || right.trivial()) return false; + + right.cast(type_date); + return left._date > right._date; + } + break; + case type_duration: - if (left.trivial () || right.trivial ()) - return false; + switch (right._type) { + case type_boolean: + case type_integer: + case type_real: + case type_string: + case type_date: + case type_duration: + if (left.trivial() || right.trivial()) return false; - right.cast (type_date); - return left._date > right._date; - } - break; - - case type_duration: - switch (right._type) - { - case type_boolean: - case type_integer: - case type_real: - case type_string: - case type_date: - case type_duration: - if (left.trivial () || right.trivial ()) - return false; - - right.cast (type_duration); - return left._duration > right._duration; - } - break; + right.cast(type_duration); + return left._duration > right._duration; + } + break; } return false; } //////////////////////////////////////////////////////////////////////////////// -bool Variant::operator>= (const Variant& other) const -{ - Variant left (*this); - Variant right (other); +bool Variant::operator>=(const Variant& other) const { + Variant left(*this); + Variant right(other); - if (left._type == type_string) - Lexer::dequote (left._string); + if (left._type == type_string) Lexer::dequote(left._string); - if (right._type == type_string) - Lexer::dequote (right._string); + if (right._type == type_string) Lexer::dequote(right._string); - switch (left._type) - { - case type_boolean: - switch (right._type) - { - case type_boolean: return left._bool || !right._bool; - case type_integer: left.cast (type_integer); return left._integer >= right._integer; - case type_real: left.cast (type_real); return left._real >= right._real; - case type_string: left.cast (type_string); return left._string >= right._string; - case type_date: left.cast (type_date); return left._date >= right._date; - case type_duration: left.cast (type_duration); return left._duration >= right._duration; - } - break; - - case type_integer: - switch (right._type) - { - case type_boolean: right.cast (type_integer); return left._integer >= right._integer; - case type_integer: return left._integer >= right._integer; - case type_real: left.cast (type_real); return left._real >= right._real; - case type_string: left.cast (type_string); return left._string >= right._string; - case type_date: left.cast (type_date); return left._date >= right._date; - case type_duration: left.cast (type_duration); return left._duration >= right._duration; - } - break; - - case type_real: - switch (right._type) - { - case type_boolean: right.cast (type_real); return left._real >= right._real; - case type_integer: right.cast (type_real); return left._real >= right._real; - case type_real: return left._real >= right._real; - case type_string: left.cast (type_string); return left._string >= right._string; - case type_date: left.cast (type_date); return left._date >= right._date; - case type_duration: left.cast (type_duration); return left._duration >= right._duration; - } - break; - - case type_string: - switch (right._type) - { + switch (left._type) { case type_boolean: - case type_integer: - case type_real: - right.cast (type_string); - return left._string >= right._string; - - case type_string: - { - if (left._string == right._string) - return true; - - auto order = Task::customOrder.find (left.source ()); - if (order != Task::customOrder.end ()) - { - // Guaranteed to be found, because of ColUDA::validate (). - auto posLeft = std::find (order->second.begin (), order->second.end (), left._string); - auto posRight = std::find (order->second.begin (), order->second.end (), right._string); - return posLeft >= posRight; - } - else - { - if (left.trivial () || right.trivial ()) - return false; - + switch (right._type) { + case type_boolean: + return left._bool || !right._bool; + case type_integer: + left.cast(type_integer); + return left._integer >= right._integer; + case type_real: + left.cast(type_real); + return left._real >= right._real; + case type_string: + left.cast(type_string); return left._string >= right._string; - } + case type_date: + left.cast(type_date); + return left._date >= right._date; + case type_duration: + left.cast(type_duration); + return left._duration >= right._duration; } + break; - case type_date: - if (left.trivial () || right.trivial ()) - return false; - - left.cast (type_date); - return left._date >= right._date; - - case type_duration: - if (left.trivial () || right.trivial ()) - return false; - - left.cast (type_duration); - return left._duration >= right._duration; - } - break; - - case type_date: - switch (right._type) - { - case type_boolean: case type_integer: + switch (right._type) { + case type_boolean: + right.cast(type_integer); + return left._integer >= right._integer; + case type_integer: + return left._integer >= right._integer; + case type_real: + left.cast(type_real); + return left._real >= right._real; + case type_string: + left.cast(type_string); + return left._string >= right._string; + case type_date: + left.cast(type_date); + return left._date >= right._date; + case type_duration: + left.cast(type_duration); + return left._duration >= right._duration; + } + break; + case type_real: + switch (right._type) { + case type_boolean: + right.cast(type_real); + return left._real >= right._real; + case type_integer: + right.cast(type_real); + return left._real >= right._real; + case type_real: + return left._real >= right._real; + case type_string: + left.cast(type_string); + return left._string >= right._string; + case type_date: + left.cast(type_date); + return left._date >= right._date; + case type_duration: + left.cast(type_duration); + return left._duration >= right._duration; + } + break; + case type_string: + switch (right._type) { + case type_boolean: + case type_integer: + case type_real: + right.cast(type_string); + return left._string >= right._string; + + case type_string: { + if (left._string == right._string) return true; + + auto order = Task::customOrder.find(left.source()); + if (order != Task::customOrder.end()) { + // Guaranteed to be found, because of ColUDA::validate (). + auto posLeft = std::find(order->second.begin(), order->second.end(), left._string); + auto posRight = std::find(order->second.begin(), order->second.end(), right._string); + return posLeft >= posRight; + } else { + if (left.trivial() || right.trivial()) return false; + + return left._string >= right._string; + } + } + + case type_date: + if (left.trivial() || right.trivial()) return false; + + left.cast(type_date); + return left._date >= right._date; + + case type_duration: + if (left.trivial() || right.trivial()) return false; + + left.cast(type_duration); + return left._duration >= right._duration; + } + break; + case type_date: + switch (right._type) { + case type_boolean: + case type_integer: + case type_real: + case type_string: + case type_date: + case type_duration: + if (left.trivial() || right.trivial()) return false; + + right.cast(type_date); + return left._date >= right._date; + } + break; + case type_duration: - if (left.trivial () || right.trivial ()) - return false; + switch (right._type) { + case type_boolean: + case type_integer: + case type_real: + case type_string: + case type_date: + case type_duration: + if (left.trivial() || right.trivial()) return false; - right.cast (type_date); - return left._date >= right._date; - } - break; - - case type_duration: - switch (right._type) - { - case type_boolean: - case type_integer: - case type_real: - case type_string: - case type_date: - case type_duration: - if (left.trivial () || right.trivial ()) - return false; - - right.cast (type_duration); - return left._duration >= right._duration; - } - break; + right.cast(type_duration); + return left._duration >= right._duration; + } + break; } return false; } //////////////////////////////////////////////////////////////////////////////// -bool Variant::operator== (const Variant& other) const -{ - Variant left (*this); - Variant right (other); +bool Variant::operator==(const Variant& other) const { + Variant left(*this); + Variant right(other); - if (left._type == type_string) - Lexer::dequote (left._string); + if (left._type == type_string) Lexer::dequote(left._string); - if (right._type == type_string) - Lexer::dequote (right._string); + if (right._type == type_string) Lexer::dequote(right._string); - switch (left._type) - { - case type_boolean: - switch (right._type) - { - case type_boolean: return left._bool == right._bool; - case type_integer: left.cast (type_integer); return left._integer == right._integer; - case type_real: left.cast (type_real); return left._real == right._real; - case type_string: left.cast (type_string); return left._string == right._string; - case type_date: left.cast (type_date); return left._date == right._date; - case type_duration: left.cast (type_duration); return left._duration == right._duration; - } - break; - - case type_integer: - switch (right._type) - { - case type_boolean: right.cast (type_integer); return left._integer == right._integer; - case type_integer: return left._integer == right._integer; - case type_real: left.cast (type_real); return left._real == right._real; - case type_string: left.cast (type_string); return left._string == right._string; - case type_date: left.cast (type_date); return left._date == right._date; - case type_duration: left.cast (type_duration); return left._duration == right._duration; - } - break; - - case type_real: - switch (right._type) - { - case type_boolean: right.cast (type_real); return left._real == right._real; - case type_integer: right.cast (type_real); return left._real == right._real; - case type_real: return left._real == right._real; - case type_string: left.cast (type_string); return left._string == right._string; - case type_date: left.cast (type_date); return left._date == right._date; - case type_duration: left.cast (type_duration); return left._duration == right._duration; - } - break; - - case type_string: - switch (right._type) - { + switch (left._type) { case type_boolean: + switch (right._type) { + case type_boolean: + return left._bool == right._bool; + case type_integer: + left.cast(type_integer); + return left._integer == right._integer; + case type_real: + left.cast(type_real); + return left._real == right._real; + case type_string: + left.cast(type_string); + return left._string == right._string; + case type_date: + left.cast(type_date); + return left._date == right._date; + case type_duration: + left.cast(type_duration); + return left._duration == right._duration; + } + break; + case type_integer: + switch (right._type) { + case type_boolean: + right.cast(type_integer); + return left._integer == right._integer; + case type_integer: + return left._integer == right._integer; + case type_real: + left.cast(type_real); + return left._real == right._real; + case type_string: + left.cast(type_string); + return left._string == right._string; + case type_date: + left.cast(type_date); + return left._date == right._date; + case type_duration: + left.cast(type_duration); + return left._duration == right._duration; + } + break; + case type_real: + switch (right._type) { + case type_boolean: + right.cast(type_real); + return left._real == right._real; + case type_integer: + right.cast(type_real); + return left._real == right._real; + case type_real: + return left._real == right._real; + case type_string: + left.cast(type_string); + return left._string == right._string; + case type_date: + left.cast(type_date); + return left._date == right._date; + case type_duration: + left.cast(type_duration); + return left._duration == right._duration; + } + break; + case type_string: - right.cast (type_string); + switch (right._type) { + case type_boolean: + case type_integer: + case type_real: + case type_string: + right.cast(type_string); - // Status is always compared caseless. - if (left.source () == "status") - return compare (left._string, right._string, false); + // Status is always compared caseless. + if (left.source() == "status") return compare(left._string, right._string, false); - return left._string == right._string; + return left._string == right._string; + + case type_date: + if (left.trivial() || right.trivial()) return false; + + left.cast(type_date); + return left._date == right._date; + + case type_duration: + left.cast(type_duration); + return left._duration == right._duration; + } + break; case type_date: - if (left.trivial () || right.trivial ()) - return false; + switch (right._type) { + case type_boolean: + case type_integer: + case type_real: + case type_string: + case type_date: + case type_duration: + if (left.trivial() || right.trivial()) return false; - left.cast (type_date); - return left._date == right._date; + right.cast(type_date); + return left._date == right._date; + } + break; case type_duration: - left.cast (type_duration); - return left._duration == right._duration; - } - break; - - case type_date: - switch (right._type) - { - case type_boolean: - case type_integer: - case type_real: - case type_string: - case type_date: - case type_duration: - if (left.trivial () || right.trivial ()) - return false; - - right.cast (type_date); - return left._date == right._date; - } - break; - - case type_duration: - switch (right._type) - { - case type_boolean: - case type_integer: - case type_real: - case type_string: - case type_date: - case type_duration: - right.cast (type_duration); - return left._duration == right._duration; - } - break; + switch (right._type) { + case type_boolean: + case type_integer: + case type_real: + case type_string: + case type_date: + case type_duration: + right.cast(type_duration); + return left._duration == right._duration; + } + break; } return false; } //////////////////////////////////////////////////////////////////////////////// -bool Variant::operator!= (const Variant& other) const -{ - return !(*this == other); -} +bool Variant::operator!=(const Variant& other) const { return !(*this == other); } //////////////////////////////////////////////////////////////////////////////// -bool Variant::operator_match (const Variant& other, const Task& task) const -{ +bool Variant::operator_match(const Variant& other, const Task& task) const { // Simple matching case first. - Variant left (*this); - Variant right (other); + Variant left(*this); + Variant right(other); - if (left._type == type_string) - Lexer::dequote (left._string); + if (left._type == type_string) Lexer::dequote(left._string); - if (right._type == type_string) - Lexer::dequote (right._string); + if (right._type == type_string) Lexer::dequote(right._string); - left.cast (type_string); - right.cast (type_string); + left.cast(type_string); + right.cast(type_string); std::string pattern = right._string; - Lexer::dequote (pattern); + Lexer::dequote(pattern); - if (searchUsingRegex) - { - RX r (pattern, searchCaseSensitive); - if (r.match (left._string)) - return true; + if (searchUsingRegex) { + RX r(pattern, searchCaseSensitive); + if (r.match(left._string)) return true; // If the above did not match, and the left source is "description", then // in the annotations. - if (left.source () == "description") - { - for (auto& a : task.getAnnotations ()) - if (r.match (a.second)) - return true; + if (left.source() == "description") { + for (auto& a : task.getAnnotations()) + if (r.match(a.second)) return true; } - } - else - { + } else { // If pattern starts with '^', look for a leftmost compare only. - if (pattern[0] == '^' && - find (left._string, - pattern.substr (1), - searchCaseSensitive) == 0) - { + if (pattern[0] == '^' && find(left._string, pattern.substr(1), searchCaseSensitive) == 0) { return true; } // If pattern ends with '$', look for a rightmost compare only. - else if (pattern[pattern.length () - 1] == '$' && - find (left._string, - pattern.substr (0, pattern.length () - 1), - searchCaseSensitive) == (left._string.length () - pattern.length () + 1)) - { + else if (pattern[pattern.length() - 1] == '$' && + find(left._string, pattern.substr(0, pattern.length() - 1), searchCaseSensitive) == + (left._string.length() - pattern.length() + 1)) { return true; } - else if (find (left._string, pattern, searchCaseSensitive) != std::string::npos) + else if (find(left._string, pattern, searchCaseSensitive) != std::string::npos) return true; // If the above did not match, and the left source is "description", then // in the annotations. - if (left.source () == "description") - { - for (auto& a : task.getAnnotations ()) - if (find (a.second, pattern, searchCaseSensitive) != std::string::npos) - return true; + if (left.source() == "description") { + for (auto& a : task.getAnnotations()) + if (find(a.second, pattern, searchCaseSensitive) != std::string::npos) return true; } } @@ -955,9 +972,8 @@ bool Variant::operator_match (const Variant& other, const Task& task) const } //////////////////////////////////////////////////////////////////////////////// -bool Variant::operator_nomatch (const Variant& other, const Task& task) const -{ - return ! operator_match (other, task); +bool Variant::operator_nomatch(const Variant& other, const Task& task) const { + return !operator_match(other, task); } //////////////////////////////////////////////////////////////////////////////// @@ -966,178 +982,173 @@ bool Variant::operator_nomatch (const Variant& other, const Task& task) const // date date --> same day check // string string --> leftmost // -bool Variant::operator_partial (const Variant& other) const -{ - Variant left (*this); - Variant right (other); +bool Variant::operator_partial(const Variant& other) const { + Variant left(*this); + Variant right(other); - if (left._type == type_string) - Lexer::dequote (left._string); + if (left._type == type_string) Lexer::dequote(left._string); - if (right._type == type_string) - Lexer::dequote (right._string); + if (right._type == type_string) Lexer::dequote(right._string); - switch (left._type) - { - case type_boolean: - switch (right._type) - { - case type_boolean: return left._bool == right._bool; - case type_integer: left.cast (type_integer); return left._integer == right._integer; - case type_real: left.cast (type_real); return left._real == right._real; - case type_string: left.cast (type_string); return left._string == right._string; - - // Same-day comparison. - case type_date: - { - left.cast (type_date); - Datetime left_date (left._date); - Datetime right_date (right._date); - return left_date.sameDay (right_date); - } - - case type_duration: left.cast (type_duration); return left._duration == right._duration; - } - break; - - case type_integer: - switch (right._type) - { - case type_boolean: right.cast (type_integer); return left._integer == right._integer; - case type_integer: return left._integer == right._integer; - case type_real: left.cast (type_real); return left._real == right._real; - case type_string: left.cast (type_string); return left._string == right._string; - - // Same-day comparison. - case type_date: - { - left.cast (type_date); - Datetime left_date (left._date); - Datetime right_date (right._date); - return left_date.sameDay (right_date); - } - - case type_duration: left.cast (type_duration); return left._duration == right._duration; - } - break; - - case type_real: - switch (right._type) - { + switch (left._type) { case type_boolean: + switch (right._type) { + case type_boolean: + return left._bool == right._bool; + case type_integer: + left.cast(type_integer); + return left._integer == right._integer; + case type_real: + left.cast(type_real); + return left._real == right._real; + case type_string: + left.cast(type_string); + return left._string == right._string; + + // Same-day comparison. + case type_date: { + left.cast(type_date); + Datetime left_date(left._date); + Datetime right_date(right._date); + return left_date.sameDay(right_date); + } + + case type_duration: + left.cast(type_duration); + return left._duration == right._duration; + } + break; + case type_integer: + switch (right._type) { + case type_boolean: + right.cast(type_integer); + return left._integer == right._integer; + case type_integer: + return left._integer == right._integer; + case type_real: + left.cast(type_real); + return left._real == right._real; + case type_string: + left.cast(type_string); + return left._string == right._string; + + // Same-day comparison. + case type_date: { + left.cast(type_date); + Datetime left_date(left._date); + Datetime right_date(right._date); + return left_date.sameDay(right_date); + } + + case type_duration: + left.cast(type_duration); + return left._duration == right._duration; + } + break; + case type_real: - right.cast (type_real); - return left._real == right._real; + switch (right._type) { + case type_boolean: + case type_integer: + case type_real: + right.cast(type_real); + return left._real == right._real; + + case type_string: + left.cast(type_string); + return left._string == right._string; + + // Same-day comparison. + case type_date: { + left.cast(type_date); + Datetime left_date(left._date); + Datetime right_date(right._date); + return left_date.sameDay(right_date); + } + + case type_duration: + left.cast(type_duration); + return left._duration == right._duration; + } + break; case type_string: - left.cast (type_string); - return left._string == right._string; + switch (right._type) { + case type_boolean: + case type_integer: + case type_real: + case type_string: { + right.cast(type_string); - // Same-day comparison. - case type_date: - { - left.cast (type_date); - Datetime left_date (left._date); - Datetime right_date (right._date); - return left_date.sameDay (right_date); + // Status is always compared caseless. + if (left.source() == "status") return compare(left._string, right._string, false); + + int left_len = left._string.length(); + int right_len = right._string.length(); + + if ((left_len == 0 && right_len != 0) || (left_len != 0 && right_len == 0)) return false; + + // Dodgy. + if (left._string.length() < right._string.length()) return false; + + return left._string.substr(0, right._string.length()) == right._string; + } + + // Same-day comparison. + case type_date: { + if (left.trivial() || right.trivial()) return false; + + left.cast(type_date); + Datetime left_date(left._date); + Datetime right_date(right._date); + return left_date.sameDay(right_date); + } + + case type_duration: + left.cast(type_duration); + return left._duration == right._duration; } + break; + + case type_date: + switch (right._type) { + // Same-day comparison. + case type_string: { + if (left.trivial() || right.trivial()) return false; + + right.cast(type_date); + Datetime left_date(left._date); + Datetime right_date(right._date); + return left_date.sameDay(right_date); + } + + case type_boolean: + case type_integer: + case type_real: + case type_date: + case type_duration: { + right.cast(type_date); + Datetime left_date(left._date); + Datetime right_date(right._date); + return left_date.sameDay(right_date); + } + } + break; case type_duration: - left.cast (type_duration); - return left._duration == right._duration; - } - break; - - case type_string: - switch (right._type) - { - case type_boolean: - case type_integer: - case type_real: - case type_string: - { - right.cast (type_string); - - // Status is always compared caseless. - if (left.source () == "status") - return compare (left._string, right._string, false); - - int left_len = left._string.length (); - int right_len = right._string.length (); - - if ((left_len == 0 && right_len != 0) || - (left_len != 0 && right_len == 0)) - return false; - - // Dodgy. - if (left._string.length () < right._string.length ()) - return false; - - return left._string.substr (0, right._string.length ()) == right._string; + switch (right._type) { + // Same-day comparison. + case type_boolean: + case type_integer: + case type_real: + case type_string: + case type_date: + case type_duration: + right.cast(type_duration); + return left._duration == right._duration; } - - // Same-day comparison. - case type_date: - { - if (left.trivial () || right.trivial ()) - return false; - - left.cast (type_date); - Datetime left_date (left._date); - Datetime right_date (right._date); - return left_date.sameDay (right_date); - } - - case type_duration: - left.cast (type_duration); - return left._duration == right._duration; - } - break; - - case type_date: - switch (right._type) - { - // Same-day comparison. - case type_string: - { - if (left.trivial () || right.trivial ()) - return false; - - right.cast (type_date); - Datetime left_date (left._date); - Datetime right_date (right._date); - return left_date.sameDay (right_date); - } - - case type_boolean: - case type_integer: - case type_real: - case type_date: - case type_duration: - { - right.cast (type_date); - Datetime left_date (left._date); - Datetime right_date (right._date); - return left_date.sameDay (right_date); - } - } - break; - - case type_duration: - switch (right._type) - { - // Same-day comparison. - case type_boolean: - case type_integer: - case type_real: - case type_string: - case type_date: - case type_duration: - right.cast (type_duration); - return left._duration == right._duration; - } - break; + break; } return false; @@ -1145,860 +1156,947 @@ bool Variant::operator_partial (const Variant& other) const //////////////////////////////////////////////////////////////////////////////// // Inverse of operator_partial. -bool Variant::operator_nopartial (const Variant& other) const -{ - return ! operator_partial (other); +bool Variant::operator_nopartial(const Variant& other) const { return !operator_partial(other); } + +//////////////////////////////////////////////////////////////////////////////// +bool Variant::operator_hastag(const Variant& other, const Task& task) const { + Variant right(other); + right.cast(type_string); + Lexer::dequote(right._string); + return task.hasTag(right._string); } //////////////////////////////////////////////////////////////////////////////// -bool Variant::operator_hastag (const Variant& other, const Task& task) const -{ - Variant right (other); - right.cast (type_string); - Lexer::dequote (right._string); - return task.hasTag (right._string); +bool Variant::operator_notag(const Variant& other, const Task& task) const { + return !operator_hastag(other, task); } //////////////////////////////////////////////////////////////////////////////// -bool Variant::operator_notag (const Variant& other, const Task& task) const -{ - return ! operator_hastag (other, task); +bool Variant::operator!() const { + Variant left(*this); + + if (left._type == type_string) Lexer::dequote(left._string); + + left.cast(type_boolean); + return !left._bool; } //////////////////////////////////////////////////////////////////////////////// -bool Variant::operator! () const -{ - Variant left (*this); +Variant& Variant::operator^=(const Variant& other) { + switch (_type) { + case type_boolean: + throw std::string(STRING_VARIANT_EXP_BOOL); + break; - if (left._type == type_string) - Lexer::dequote (left._string); + case type_integer: + switch (other._type) { + case type_boolean: + throw std::string(STRING_VARIANT_EXP_BOOL); + case type_integer: + _integer = (int)pow(static_cast(_integer), static_cast(other._integer)); + break; + case type_real: + throw std::string(STRING_VARIANT_EXP_NON_INT); + case type_string: + throw std::string(STRING_VARIANT_EXP_STRING); + case type_date: + throw std::string(STRING_VARIANT_EXP_DATE); + case type_duration: + throw std::string(STRING_VARIANT_EXP_DURATION); + } + break; - left.cast (type_boolean); - return ! left._bool; -} + case type_real: + switch (other._type) { + case type_boolean: + throw std::string(STRING_VARIANT_EXP_BOOL); + case type_integer: + _real = pow(_real, static_cast(other._integer)); + break; + case type_real: + throw std::string(STRING_VARIANT_EXP_NON_INT); + case type_string: + throw std::string(STRING_VARIANT_EXP_STRING); + case type_date: + throw std::string(STRING_VARIANT_EXP_DATE); + case type_duration: + throw std::string(STRING_VARIANT_EXP_DURATION); + } + break; -//////////////////////////////////////////////////////////////////////////////// -Variant& Variant::operator^= (const Variant& other) -{ - switch (_type) - { - case type_boolean: - throw std::string (STRING_VARIANT_EXP_BOOL); - break; + case type_string: + throw std::string(STRING_VARIANT_EXP_STRING); + break; - case type_integer: - switch (other._type) - { - case type_boolean: throw std::string (STRING_VARIANT_EXP_BOOL); - case type_integer: _integer = (int) pow (static_cast(_integer), static_cast(other._integer)); break; - case type_real: throw std::string (STRING_VARIANT_EXP_NON_INT); - case type_string: throw std::string (STRING_VARIANT_EXP_STRING); - case type_date: throw std::string (STRING_VARIANT_EXP_DATE); - case type_duration: throw std::string (STRING_VARIANT_EXP_DURATION); - } - break; + case type_date: + throw std::string(STRING_VARIANT_EXP_DATE); + break; - case type_real: - switch (other._type) - { - case type_boolean: throw std::string (STRING_VARIANT_EXP_BOOL); - case type_integer: _real = pow (_real, static_cast(other._integer)); break; - case type_real: throw std::string (STRING_VARIANT_EXP_NON_INT); - case type_string: throw std::string (STRING_VARIANT_EXP_STRING); - case type_date: throw std::string (STRING_VARIANT_EXP_DATE); - case type_duration: throw std::string (STRING_VARIANT_EXP_DURATION); - } - break; - - case type_string: - throw std::string (STRING_VARIANT_EXP_STRING); - break; - - case type_date: - throw std::string (STRING_VARIANT_EXP_DATE); - break; - - case type_duration: - throw std::string (STRING_VARIANT_EXP_DURATION); - break; + case type_duration: + throw std::string(STRING_VARIANT_EXP_DURATION); + break; } return *this; } //////////////////////////////////////////////////////////////////////////////// -Variant Variant::operator^ (const Variant& other) const -{ - Variant left (*this); +Variant Variant::operator^(const Variant& other) const { + Variant left(*this); left ^= other; return left; } //////////////////////////////////////////////////////////////////////////////// -Variant& Variant::operator-= (const Variant& other) -{ - Variant right (other); - - switch (_type) - { - case type_boolean: - throw std::string (STRING_VARIANT_SUB_BOOL); - break; - - case type_integer: - switch (right._type) - { - case type_boolean: right.cast (type_integer); _integer -= right._integer; break; - case type_integer: _integer -= right._integer; break; - case type_real: cast (type_real); _real -= right._real; break; - case type_string: throw std::string (STRING_VARIANT_SUB_STRING); - case type_date: cast (type_date); _date -= right._date; break; - case type_duration: cast (type_duration); _duration -= right._duration; break; - } - break; - - case type_real: - switch (right._type) - { - case type_string: - throw std::string (STRING_VARIANT_SUB_STRING); +Variant& Variant::operator-=(const Variant& other) { + Variant right(other); + switch (_type) { case type_boolean: - case type_integer: - case type_real: - case type_date: - case type_duration: - right.cast (type_real); - _real -= right._real; + throw std::string(STRING_VARIANT_SUB_BOOL); + break; + + case type_integer: + switch (right._type) { + case type_boolean: + right.cast(type_integer); + _integer -= right._integer; + break; + case type_integer: + _integer -= right._integer; + break; + case type_real: + cast(type_real); + _real -= right._real; + break; + case type_string: + throw std::string(STRING_VARIANT_SUB_STRING); + case type_date: + cast(type_date); + _date -= right._date; + break; + case type_duration: + cast(type_duration); + _duration -= right._duration; + break; + } + break; + + case type_real: + switch (right._type) { + case type_string: + throw std::string(STRING_VARIANT_SUB_STRING); + + case type_boolean: + case type_integer: + case type_real: + case type_date: + case type_duration: + right.cast(type_real); + _real -= right._real; + break; + } break; - } - break; - case type_string: - switch (right._type) - { case type_string: - cast (type_string); _string += '-' + right._string; break; - case type_boolean: - case type_integer: - case type_real: - case type_date: - case type_duration: - throw std::string (STRING_VARIANT_SUB_STRING); + switch (right._type) { + case type_string: + cast(type_string); + _string += '-' + right._string; + break; + case type_boolean: + case type_integer: + case type_real: + case type_date: + case type_duration: + throw std::string(STRING_VARIANT_SUB_STRING); + break; + } break; - } - break; - case type_date: - switch (right._type) - { - case type_boolean: right.cast (type_integer); _date -= right._integer; break; - case type_integer: _date -= right._integer; break; - case type_real: _date -= (int) right._real; break; - case type_string: throw std::string (STRING_VARIANT_SUB_STRING); - case type_date: _type = Variant::type_duration; _duration = _date - right._date; break; - case type_duration: _date -= right._duration; break; - } - break; + case type_date: + switch (right._type) { + case type_boolean: + right.cast(type_integer); + _date -= right._integer; + break; + case type_integer: + _date -= right._integer; + break; + case type_real: + _date -= (int)right._real; + break; + case type_string: + throw std::string(STRING_VARIANT_SUB_STRING); + case type_date: + _type = Variant::type_duration; + _duration = _date - right._date; + break; + case type_duration: + _date -= right._duration; + break; + } + break; - case type_duration: - switch (right._type) - { - case type_boolean: right.cast (type_integer); _duration -= right._integer; break; - case type_integer: _duration -= right._integer; break; - case type_real: _duration -= (int) right._real; break; - case type_string: throw std::string (STRING_VARIANT_SUB_STRING); - case type_date: throw std::string (STRING_VARIANT_SUB_DATE); - case type_duration: _duration -= right._duration; break; - } - break; + case type_duration: + switch (right._type) { + case type_boolean: + right.cast(type_integer); + _duration -= right._integer; + break; + case type_integer: + _duration -= right._integer; + break; + case type_real: + _duration -= (int)right._real; + break; + case type_string: + throw std::string(STRING_VARIANT_SUB_STRING); + case type_date: + throw std::string(STRING_VARIANT_SUB_DATE); + case type_duration: + _duration -= right._duration; + break; + } + break; } return *this; } //////////////////////////////////////////////////////////////////////////////// -Variant Variant::operator- (const Variant& other) const -{ - Variant left (*this); +Variant Variant::operator-(const Variant& other) const { + Variant left(*this); left -= other; return left; } //////////////////////////////////////////////////////////////////////////////// -Variant& Variant::operator+= (const Variant& other) -{ - Variant right (other); +Variant& Variant::operator+=(const Variant& other) { + Variant right(other); - if (right._type == type_string) - Lexer::dequote (right._string); + if (right._type == type_string) Lexer::dequote(right._string); - switch (_type) - { - case type_boolean: - switch (right._type) - { - case type_boolean: throw std::string (STRING_VARIANT_ADD_BOOL); - case type_integer: cast (type_integer); _integer += right._integer; break; - case type_real: cast (type_real); _real += right._real; break; - case type_string: cast (type_string); _string += right._string; break; - case type_date: cast (type_date); _date += right._date; break; - case type_duration: cast (type_duration); _duration += right._duration; break; - } - break; - - case type_integer: - switch (right._type) - { - case type_boolean: right.cast (type_integer); _integer += right._integer; break; - case type_integer: _integer += right._integer; break; - case type_real: cast (type_real); _real += right._real; break; - case type_string: cast (type_string); _string += right._string; break; - case type_date: cast (type_date); _date += right._date; break; - case type_duration: cast (type_duration); _duration += right._duration; break; - } - break; - - case type_real: - switch (right._type) - { + switch (_type) { case type_boolean: + switch (right._type) { + case type_boolean: + throw std::string(STRING_VARIANT_ADD_BOOL); + case type_integer: + cast(type_integer); + _integer += right._integer; + break; + case type_real: + cast(type_real); + _real += right._real; + break; + case type_string: + cast(type_string); + _string += right._string; + break; + case type_date: + cast(type_date); + _date += right._date; + break; + case type_duration: + cast(type_duration); + _duration += right._duration; + break; + } + break; + case type_integer: + switch (right._type) { + case type_boolean: + right.cast(type_integer); + _integer += right._integer; + break; + case type_integer: + _integer += right._integer; + break; + case type_real: + cast(type_real); + _real += right._real; + break; + case type_string: + cast(type_string); + _string += right._string; + break; + case type_date: + cast(type_date); + _date += right._date; + break; + case type_duration: + cast(type_duration); + _duration += right._duration; + break; + } + break; + case type_real: - right.cast (type_real); - _real += right._real; + switch (right._type) { + case type_boolean: + case type_integer: + case type_real: + right.cast(type_real); + _real += right._real; + break; + + case type_string: + cast(type_string); + _string += right._string; + break; + + case type_date: + _type = type_date; + _date = (unsigned)(int)_real + right._date; + break; + + case type_duration: + _type = type_duration; + _duration = (unsigned)(int)_real + right._duration; + break; + } break; case type_string: - cast (type_string); - _string += right._string; + _string += (std::string)right; break; case type_date: - _type = type_date; - _date = (unsigned) (int) _real + right._date; + switch (right._type) { + case type_boolean: + right.cast(type_date); + _date += right._date; + break; + case type_integer: + _date += right._integer; + break; + case type_real: + _date += (int)right._real; + break; + case type_string: + cast(type_string); + _string += right._string; + break; + case type_date: + throw std::string(STRING_VARIANT_ADD_DATE); + case type_duration: + _date += right._duration; + break; + } break; case type_duration: - _type = type_duration; - _duration = (unsigned) (int) _real + right._duration; + switch (right._type) { + case type_boolean: + right.cast(type_duration); + _duration += right._duration; + break; + case type_integer: + _duration += right._integer; + break; + case type_real: + _duration += (int)right._real; + break; + case type_string: + cast(type_string); + _string += right._string; + break; + case type_date: + _type = Variant::type_date; + _date += right._date + _duration; + break; + case type_duration: + _duration += right._duration; + break; + } break; - } - break; - - case type_string: - _string += (std::string) right; - break; - - case type_date: - switch (right._type) - { - case type_boolean: right.cast (type_date); _date += right._date; break; - case type_integer: _date += right._integer; break; - case type_real: _date += (int) right._real; break; - case type_string: cast (type_string); _string += right._string; break; - case type_date: throw std::string (STRING_VARIANT_ADD_DATE); - case type_duration: _date += right._duration; break; - } - break; - - case type_duration: - switch (right._type) - { - case type_boolean: right.cast (type_duration); _duration += right._duration; break; - case type_integer: _duration += right._integer; break; - case type_real: _duration += (int) right._real; break; - case type_string: cast (type_string); _string += right._string; break; - case type_date: _type = Variant::type_date; _date += right._date + _duration; break; - case type_duration: _duration += right._duration; break; - } - break; } return *this; } //////////////////////////////////////////////////////////////////////////////// -Variant Variant::operator+ (const Variant& other) const -{ - Variant left (*this); +Variant Variant::operator+(const Variant& other) const { + Variant left(*this); left += other; return left; } //////////////////////////////////////////////////////////////////////////////// -Variant& Variant::operator*= (const Variant& other) -{ - Variant right (other); +Variant& Variant::operator*=(const Variant& other) { + Variant right(other); - if (right._type == type_string) - Lexer::dequote (right._string); + if (right._type == type_string) Lexer::dequote(right._string); - switch (_type) - { - case type_boolean: - switch (right._type) - { - case type_boolean: throw std::string (STRING_VARIANT_MUL_BOOL); - case type_integer: cast (type_integer); _integer *= right._integer; break; - case type_real: cast (type_real); _real *= right._real; break; - case type_string: _string = (_bool ? right._string : ""); _type = type_string; break; - case type_date: throw std::string (STRING_VARIANT_MUL_DATE); - case type_duration: cast (type_duration); _duration *= right._duration; break; - } - break; - - case type_integer: - switch (right._type) - { - case type_boolean: right.cast (type_integer); _integer *= right._integer; break; - case type_integer: _integer *= right._integer; break; - case type_real: cast (type_real); _real *= right._real; break; - case type_string: - { - int limit = _integer; - // assert (limit < 128); - _type = type_string; - _string = ""; - while (limit--) - _string += right._string; + switch (_type) { + case type_boolean: + switch (right._type) { + case type_boolean: + throw std::string(STRING_VARIANT_MUL_BOOL); + case type_integer: + cast(type_integer); + _integer *= right._integer; + break; + case type_real: + cast(type_real); + _real *= right._real; + break; + case type_string: + _string = (_bool ? right._string : ""); + _type = type_string; + break; + case type_date: + throw std::string(STRING_VARIANT_MUL_DATE); + case type_duration: + cast(type_duration); + _duration *= right._duration; + break; } break; - case type_date: throw std::string (STRING_VARIANT_MUL_DATE); - case type_duration: cast (type_duration); _duration *= right._duration; break; - } - break; - case type_real: - switch (right._type) - { - case type_boolean: case type_integer: + switch (right._type) { + case type_boolean: + right.cast(type_integer); + _integer *= right._integer; + break; + case type_integer: + _integer *= right._integer; + break; + case type_real: + cast(type_real); + _real *= right._real; + break; + case type_string: { + int limit = _integer; + // assert (limit < 128); + _type = type_string; + _string = ""; + while (limit--) _string += right._string; + } break; + case type_date: + throw std::string(STRING_VARIANT_MUL_DATE); + case type_duration: + cast(type_duration); + _duration *= right._duration; + break; + } + break; + case type_real: - right.cast (type_real); - _real *= right._real; + switch (right._type) { + case type_boolean: + case type_integer: + case type_real: + right.cast(type_real); + _real *= right._real; + break; + + case type_string: + throw std::string(STRING_VARIANT_MUL_REAL_STR); + + case type_date: + throw std::string(STRING_VARIANT_MUL_DATE); + + case type_duration: + _type = type_duration; + _duration = (time_t)(unsigned)(int)(_real * static_cast(right._duration)); + } break; case type_string: - throw std::string (STRING_VARIANT_MUL_REAL_STR); + switch (right._type) { + case type_boolean: + if (!right._bool) _string = ""; + break; + case type_integer: { + int limit = right._integer - 1; + // assert (limit < 128); + std::string fragment = _string; + while (limit--) _string += fragment; + } break; + case type_real: + throw std::string(STRING_VARIANT_MUL_STR_REAL); + case type_string: + throw std::string(STRING_VARIANT_MUL_STR_STR); + case type_date: + throw std::string(STRING_VARIANT_MUL_STR_DATE); + case type_duration: + throw std::string(STRING_VARIANT_MUL_STR_DUR); + } + break; case type_date: - throw std::string (STRING_VARIANT_MUL_DATE); + throw std::string(STRING_VARIANT_MUL_DATE); case type_duration: - _type = type_duration; - _duration = (time_t) (unsigned) (int) (_real * static_cast(right._duration)); - } - break; - - case type_string: - switch (right._type) - { - case type_boolean: if (! right._bool) _string = ""; break; - case type_integer: - { - int limit = right._integer - 1; - // assert (limit < 128); - std::string fragment = _string; - while (limit--) - _string += fragment; + switch (right._type) { + case type_boolean: + right.cast(type_duration); + _duration *= right._duration; + break; + case type_integer: + _duration *= right._integer; + break; + case type_real: + _duration = (time_t)(unsigned)(int)(static_cast(_duration) * right._real); + break; + case type_string: + throw std::string(STRING_VARIANT_MUL_DUR_STR); + case type_date: + throw std::string(STRING_VARIANT_MUL_DUR_DATE); + case type_duration: + throw std::string(STRING_VARIANT_MUL_DUR_DUR); } break; - case type_real: throw std::string (STRING_VARIANT_MUL_STR_REAL); - case type_string: throw std::string (STRING_VARIANT_MUL_STR_STR); - case type_date: throw std::string (STRING_VARIANT_MUL_STR_DATE); - case type_duration: throw std::string (STRING_VARIANT_MUL_STR_DUR); - } - break; - - case type_date: - throw std::string (STRING_VARIANT_MUL_DATE); - - case type_duration: - switch (right._type) - { - case type_boolean: right.cast (type_duration); _duration *= right._duration; break; - case type_integer: _duration *= right._integer; break; - case type_real: - _duration = (time_t) (unsigned) (int) (static_cast(_duration) * right._real); - break; - case type_string: throw std::string (STRING_VARIANT_MUL_DUR_STR); - case type_date: throw std::string (STRING_VARIANT_MUL_DUR_DATE); - case type_duration: throw std::string (STRING_VARIANT_MUL_DUR_DUR); - } - break; } return *this; } //////////////////////////////////////////////////////////////////////////////// -Variant Variant::operator* (const Variant& other) const -{ - Variant left (*this); +Variant Variant::operator*(const Variant& other) const { + Variant left(*this); left *= other; return left; } //////////////////////////////////////////////////////////////////////////////// -Variant& Variant::operator/= (const Variant& other) -{ - Variant right (other); +Variant& Variant::operator/=(const Variant& other) { + Variant right(other); - switch (_type) - { - case type_boolean: - throw std::string (STRING_VARIANT_DIV_BOOL); - break; - - case type_integer: - switch (right._type) - { + switch (_type) { case type_boolean: - throw std::string (STRING_VARIANT_DIV_INT_BOOL); + throw std::string(STRING_VARIANT_DIV_BOOL); + break; case type_integer: - if (right._integer == 0) - throw std::string (STRING_VARIANT_DIV_ZERO); - _integer /= right._integer; + switch (right._type) { + case type_boolean: + throw std::string(STRING_VARIANT_DIV_INT_BOOL); + + case type_integer: + if (right._integer == 0) throw std::string(STRING_VARIANT_DIV_ZERO); + _integer /= right._integer; + break; + + case type_real: + if (right._real == 0.0) throw std::string(STRING_VARIANT_DIV_ZERO); + cast(type_real); + _real /= right._real; + break; + + case type_string: + throw std::string(STRING_VARIANT_DIV_INT_STR); + + case type_date: + throw std::string(STRING_VARIANT_DIV_INT_DATE); + + case type_duration: + if (right._duration == 0) throw std::string(STRING_VARIANT_DIV_ZERO); + _type = type_duration; + _duration = (time_t)(unsigned)(int)(_integer / right._duration); + break; + } break; case type_real: - if (right._real == 0.0) - throw std::string (STRING_VARIANT_DIV_ZERO); - cast (type_real); - _real /= right._real; + switch (right._type) { + case type_boolean: + throw std::string(STRING_VARIANT_DIV_REAL_BOOL); + + case type_integer: + if (right._integer == 0) throw std::string(STRING_VARIANT_DIV_ZERO); + _real /= static_cast(right._integer); + break; + + case type_real: + if (right._real == 0) throw std::string(STRING_VARIANT_DIV_ZERO); + _real /= right._real; + break; + + case type_string: + throw std::string(STRING_VARIANT_DIV_REAL_STR); + + case type_date: + throw std::string(STRING_VARIANT_DIV_REAL_DATE); + + case type_duration: + if (right._duration == 0) throw std::string(STRING_VARIANT_DIV_ZERO); + _type = type_duration; + _duration = (time_t)(unsigned)(int)(_real / right._duration); + break; + } break; case type_string: - throw std::string (STRING_VARIANT_DIV_INT_STR); + throw std::string(STRING_VARIANT_DIV_REAL_STR); + break; case type_date: - throw std::string (STRING_VARIANT_DIV_INT_DATE); + throw std::string(STRING_VARIANT_DIV_REAL_DATE); case type_duration: - if (right._duration == 0) - throw std::string (STRING_VARIANT_DIV_ZERO); - _type = type_duration; - _duration = (time_t) (unsigned) (int) (_integer / right._duration); + switch (right._type) { + case type_boolean: + throw std::string(STRING_VARIANT_DIV_DUR_BOOL); + + case type_integer: + if (right._integer == 0) throw std::string(STRING_VARIANT_DIV_ZERO); + _duration /= right._integer; + break; + + case type_real: + if (right._real == 0) throw std::string(STRING_VARIANT_DIV_ZERO); + _duration = (time_t)(unsigned)(int)(static_cast(_duration) / right._real); + break; + + case type_string: + throw std::string(STRING_VARIANT_DIV_DUR_STR); + + case type_date: + throw std::string(STRING_VARIANT_DIV_DUR_DATE); + + case type_duration: + throw std::string(STRING_VARIANT_DIV_DUR_DUR); + } break; - } - break; - - case type_real: - switch (right._type) - { - case type_boolean: - throw std::string (STRING_VARIANT_DIV_REAL_BOOL); - - case type_integer: - if (right._integer == 0) - throw std::string (STRING_VARIANT_DIV_ZERO); - _real /= static_cast(right._integer); - break; - - case type_real: - if (right._real == 0) - throw std::string (STRING_VARIANT_DIV_ZERO); - _real /= right._real; - break; - - case type_string: - throw std::string (STRING_VARIANT_DIV_REAL_STR); - - case type_date: - throw std::string (STRING_VARIANT_DIV_REAL_DATE); - - case type_duration: - if (right._duration == 0) - throw std::string (STRING_VARIANT_DIV_ZERO); - _type = type_duration; - _duration = (time_t) (unsigned) (int) (_real / right._duration); - break; - } - break; - - case type_string: - throw std::string (STRING_VARIANT_DIV_REAL_STR); - break; - - case type_date: - throw std::string (STRING_VARIANT_DIV_REAL_DATE); - - case type_duration: - switch (right._type) - { - case type_boolean: - throw std::string (STRING_VARIANT_DIV_DUR_BOOL); - - case type_integer: - if (right._integer == 0) - throw std::string (STRING_VARIANT_DIV_ZERO); - _duration /= right._integer; - break; - - case type_real: - if (right._real == 0) - throw std::string (STRING_VARIANT_DIV_ZERO); - _duration = (time_t) (unsigned) (int) (static_cast(_duration) / right._real); - break; - - case type_string: - throw std::string (STRING_VARIANT_DIV_DUR_STR); - - case type_date: - throw std::string (STRING_VARIANT_DIV_DUR_DATE); - - case type_duration: - throw std::string (STRING_VARIANT_DIV_DUR_DUR); - } - break; } return *this; } //////////////////////////////////////////////////////////////////////////////// -Variant Variant::operator/ (const Variant& other) const -{ - Variant left (*this); +Variant Variant::operator/(const Variant& other) const { + Variant left(*this); left /= other; return left; } //////////////////////////////////////////////////////////////////////////////// -Variant& Variant::operator%= (const Variant& other) -{ - Variant right (other); +Variant& Variant::operator%=(const Variant& other) { + Variant right(other); - switch (_type) - { - case type_boolean: - throw std::string (STRING_VARIANT_MOD_BOOL); - break; - - case type_integer: - switch (right._type) - { + switch (_type) { case type_boolean: - throw std::string (STRING_VARIANT_MOD_INT_BOOL); + throw std::string(STRING_VARIANT_MOD_BOOL); + break; case type_integer: - if (right._integer == 0) - throw std::string (STRING_VARIANT_MOD_ZERO); - _integer %= right._integer; + switch (right._type) { + case type_boolean: + throw std::string(STRING_VARIANT_MOD_INT_BOOL); + + case type_integer: + if (right._integer == 0) throw std::string(STRING_VARIANT_MOD_ZERO); + _integer %= right._integer; + break; + + case type_real: + if (right._real == 0.0) throw std::string(STRING_VARIANT_MOD_ZERO); + cast(type_real); + _real = fmod(_real, right._real); + break; + + case type_string: + throw std::string(STRING_VARIANT_MOD_INT_STR); + + case type_date: + throw std::string(STRING_VARIANT_MOD_INT_DATE); + + case type_duration: + throw std::string(STRING_VARIANT_MOD_INT_DUR); + } break; case type_real: - if (right._real == 0.0) - throw std::string (STRING_VARIANT_MOD_ZERO); - cast (type_real); - _real = fmod (_real, right._real); + switch (right._type) { + case type_boolean: + throw std::string(STRING_VARIANT_MOD_REAL_BOOL); + + case type_integer: + if (right._integer == 0) throw std::string(STRING_VARIANT_MOD_ZERO); + _real = fmod(_real, static_cast(right._integer)); + break; + + case type_real: + if (right._real == 0) throw std::string(STRING_VARIANT_MOD_ZERO); + _real = fmod(_real, right._real); + break; + + case type_string: + throw std::string(STRING_VARIANT_MOD_REAL_STR); + + case type_date: + throw std::string(STRING_VARIANT_MOD_REAL_DATE); + + case type_duration: + throw std::string(STRING_VARIANT_MOD_REAL_DUR); + } break; case type_string: - throw std::string (STRING_VARIANT_MOD_INT_STR); + throw std::string(STRING_VARIANT_MOD_STR); case type_date: - throw std::string (STRING_VARIANT_MOD_INT_DATE); + throw std::string(STRING_VARIANT_MOD_DATE); case type_duration: - throw std::string (STRING_VARIANT_MOD_INT_DUR); - } - break; - - case type_real: - switch (right._type) - { - case type_boolean: - throw std::string (STRING_VARIANT_MOD_REAL_BOOL); - - case type_integer: - if (right._integer == 0) - throw std::string (STRING_VARIANT_MOD_ZERO); - _real = fmod (_real, static_cast(right._integer)); - break; - - case type_real: - if (right._real == 0) - throw std::string (STRING_VARIANT_MOD_ZERO); - _real = fmod (_real, right._real); - break; - - case type_string: - throw std::string (STRING_VARIANT_MOD_REAL_STR); - - case type_date: - throw std::string (STRING_VARIANT_MOD_REAL_DATE); - - case type_duration: - throw std::string (STRING_VARIANT_MOD_REAL_DUR); - } - break; - - case type_string: - throw std::string (STRING_VARIANT_MOD_STR); - - case type_date: - throw std::string (STRING_VARIANT_MOD_DATE); - - case type_duration: - throw std::string (STRING_VARIANT_MOD_DUR); + throw std::string(STRING_VARIANT_MOD_DUR); } return *this; } //////////////////////////////////////////////////////////////////////////////// -Variant Variant::operator% (const Variant& other) const -{ - Variant left (*this); +Variant Variant::operator%(const Variant& other) const { + Variant left(*this); left %= other; return left; } //////////////////////////////////////////////////////////////////////////////// -Variant::operator std::string () const -{ - switch (_type) - { - case type_boolean: - return std::string (_bool ? "true" : "false"); +Variant::operator std::string() const { + switch (_type) { + case type_boolean: + return std::string(_bool ? "true" : "false"); - case type_integer: - { + case type_integer: { std::stringstream s; s << _integer; - return s.str (); + return s.str(); } - case type_real: - { + case type_real: { std::stringstream s; s << _real; - return s.str (); + return s.str(); } - case type_string: - return _string; + case type_string: + return _string; - case type_date: - return Datetime (_date).toISOLocalExtended (); + case type_date: + return Datetime(_date).toISOLocalExtended(); - case type_duration: - return Duration (_duration).formatISO (); + case type_duration: + return Duration(_duration).formatISO(); } return ""; } //////////////////////////////////////////////////////////////////////////////// -void Variant::sqrt () -{ - if (_type == type_string) - Lexer::dequote (_string); +void Variant::sqrt() { + if (_type == type_string) Lexer::dequote(_string); - cast (type_real); - if (_real < 0.0) - throw std::string (STRING_VARIANT_SQRT_NEG); - _real = ::sqrt (_real); + cast(type_real); + if (_real < 0.0) throw std::string(STRING_VARIANT_SQRT_NEG); + _real = ::sqrt(_real); } //////////////////////////////////////////////////////////////////////////////// -void Variant::cast (const enum type new_type) -{ +void Variant::cast(const enum type new_type) { // Short circuit. - if (_type == new_type) - return; + if (_type == new_type) return; // From type_boolean - switch (_type) - { - case type_boolean: - switch (new_type) - { - case type_boolean: break; - case type_integer: _integer = _bool ? 1 : 0; break; - case type_real: _real = _bool ? 1.0 : 0.0; break; - case type_string: _string = _bool ? "true" : "false"; break; - case type_date: _date = _bool ? 1 : 0; break; - case type_duration: _duration = _bool ? 1 : 0; break; - } - break; - - case type_integer: - switch (new_type) - { - case type_boolean: _bool = _integer == 0 ? false : true; break; - case type_integer: break; - case type_real: _real = static_cast(_integer); break; - case type_string: - { - char temp[24]; - snprintf (temp, 24, "%lld", _integer); - _string = temp; - } - break; - case type_date: _date = (time_t) _integer; break; - case type_duration: _duration = (time_t) _integer; break; - } - break; - - case type_real: - switch (new_type) - { - case type_boolean: _bool = _real == 0.0 ? false : true; break; - case type_integer: _integer = (long long) _real; break; - case type_real: break; - case type_string: - { - char temp[24]; - snprintf (temp, 24, "%g", _real); - _string = temp; - } - break; - case type_date: _date = (time_t) (int) _real; break; - case type_duration: _duration = (time_t) (int) _real; break; - } - break; - - case type_string: - Lexer::dequote (_string); - switch (new_type) - { + switch (_type) { case type_boolean: - _bool = (_string.length () == 0 || - _string == "0" || - _string == "0.0") ? false : true; + switch (new_type) { + case type_boolean: + break; + case type_integer: + _integer = _bool ? 1 : 0; + break; + case type_real: + _real = _bool ? 1.0 : 0.0; + break; + case type_string: + _string = _bool ? "true" : "false"; + break; + case type_date: + _date = _bool ? 1 : 0; + break; + case type_duration: + _duration = _bool ? 1 : 0; + break; + } break; + case type_integer: - _integer = (long long) strtol (_string.c_str (), nullptr, (_string.substr (0, 2) == "0x" ? 16 : 10)); + switch (new_type) { + case type_boolean: + _bool = _integer == 0 ? false : true; + break; + case type_integer: + break; + case type_real: + _real = static_cast(_integer); + break; + case type_string: { + char temp[24]; + snprintf(temp, 24, "%lld", _integer); + _string = temp; + } break; + case type_date: + _date = (time_t)_integer; + break; + case type_duration: + _duration = (time_t)_integer; + break; + } break; - case type_real: _real = strtod (_string.c_str (), nullptr); break; - case type_string: break; + + case type_real: + switch (new_type) { + case type_boolean: + _bool = _real == 0.0 ? false : true; + break; + case type_integer: + _integer = (long long)_real; + break; + case type_real: + break; + case type_string: { + char temp[24]; + snprintf(temp, 24, "%g", _real); + _string = temp; + } break; + case type_date: + _date = (time_t)(int)_real; + break; + case type_duration: + _duration = (time_t)(int)_real; + break; + } + break; + + case type_string: + Lexer::dequote(_string); + switch (new_type) { + case type_boolean: + _bool = (_string.length() == 0 || _string == "0" || _string == "0.0") ? false : true; + break; + case type_integer: + _integer = + (long long)strtol(_string.c_str(), nullptr, (_string.substr(0, 2) == "0x" ? 16 : 10)); + break; + case type_real: + _real = strtod(_string.c_str(), nullptr); + break; + case type_string: + break; + case type_date: { + _date = 0; + Datetime iso; + std::string::size_type pos = 0; + if (iso.parse(_string, pos, dateFormat) && pos == _string.length()) { + _date = iso.toEpoch(); + break; + } + + pos = 0; + Duration isop; + if (isop.parse(_string, pos) && pos == _string.length()) { + _date = Datetime().toEpoch() + isop.toTime_t(); + break; + } + + if (dateFormat != "") { + _date = Datetime(_string, dateFormat).toEpoch(); + break; + } + } break; + case type_duration: { + _duration = 0; + std::string::size_type pos = 0; + Duration iso; + if (iso.parse(_string, pos) && pos == _string.length()) { + _duration = iso.toTime_t(); + } + } break; + } + break; + case type_date: - { - _date = 0; - Datetime iso; - std::string::size_type pos = 0; - if (iso.parse (_string, pos, dateFormat) && - pos == _string.length ()) - { - _date = iso.toEpoch (); + switch (new_type) { + case type_boolean: + _bool = _date != 0 ? true : false; break; - } - - pos = 0; - Duration isop; - if (isop.parse (_string, pos) && - pos == _string.length ()) - { - _date = Datetime ().toEpoch () + isop.toTime_t (); + case type_integer: + _integer = (long long)_date; break; - } - - if (dateFormat != "") - { - _date = Datetime (_string, dateFormat).toEpoch (); + case type_real: + _real = static_cast(_date); + break; + case type_string: + _string = (std::string) * this; + break; + case type_date: + break; + // TODO: Not exactly correct (should duration convert into date?), but + // currently needed for symmetry, which is assumed by operators. + case type_duration: + _duration = _date - time(nullptr); break; - } } break; + case type_duration: - { - _duration = 0; - std::string::size_type pos = 0; - Duration iso; - if (iso.parse (_string, pos) && - pos == _string.length ()) - { - _duration = iso.toTime_t (); - } + switch (new_type) { + case type_boolean: + _bool = _duration != 0 ? true : false; + break; + case type_integer: + _integer = (long long)_duration; + break; + case type_real: + _real = static_cast(_duration); + break; + case type_string: + _string = (std::string) * this; + break; + case type_date: + _date = time(nullptr) + _duration; + break; + case type_duration: + break; } break; - } - break; - - case type_date: - switch (new_type) - { - case type_boolean: _bool = _date != 0 ? true : false; break; - case type_integer: _integer = (long long) _date; break; - case type_real: _real = static_cast(_date); break; - case type_string: _string = (std::string) *this; break; - case type_date: break; - // TODO: Not exactly correct (should duration convert into date?), but - // currently needed for symmetry, which is assumed by operators. - case type_duration: _duration = _date - time (nullptr); break; - } - break; - - case type_duration: - switch (new_type) - { - case type_boolean: _bool = _duration != 0 ? true : false; break; - case type_integer: _integer = (long long) _duration; break; - case type_real: _real = static_cast(_duration); break; - case type_string: _string = (std::string) *this; break; - case type_date: _date = time (nullptr) + _duration; break; - case type_duration: break; - } - break; } _type = new_type; } //////////////////////////////////////////////////////////////////////////////// -int Variant::type () -{ - return _type; -} +int Variant::type() { return _type; } //////////////////////////////////////////////////////////////////////////////// -bool Variant::trivial () const -{ - return (_type == type_integer && _integer == 0) || - (_type == type_real && _real == 0.0) || - (_type == type_string && _string == "") || - (_type == type_date && _date == 0) || +bool Variant::trivial() const { + return (_type == type_integer && _integer == 0) || (_type == type_real && _real == 0.0) || + (_type == type_string && _string == "") || (_type == type_date && _date == 0) || (_type == type_duration && _duration == 0); } //////////////////////////////////////////////////////////////////////////////// -bool Variant::get_bool () const -{ - return _bool; -} +bool Variant::get_bool() const { return _bool; } //////////////////////////////////////////////////////////////////////////////// -long long Variant::get_integer () const -{ - return _integer; -} +long long Variant::get_integer() const { return _integer; } //////////////////////////////////////////////////////////////////////////////// -double Variant::get_real () const -{ - return _real; -} +double Variant::get_real() const { return _real; } //////////////////////////////////////////////////////////////////////////////// -const std::string& Variant::get_string () const -{ - return _string; -} +const std::string& Variant::get_string() const { return _string; } //////////////////////////////////////////////////////////////////////////////// -time_t Variant::get_date () const -{ - return _date; -} +time_t Variant::get_date() const { return _date; } //////////////////////////////////////////////////////////////////////////////// -time_t Variant::get_duration () const -{ - return _duration; -} +time_t Variant::get_duration() const { return _duration; } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/Variant.h b/src/Variant.h index 2970a9e61..3cbc5c6af 100644 --- a/src/Variant.h +++ b/src/Variant.h @@ -27,94 +27,94 @@ #ifndef INCLUDED_VARIANT #define INCLUDED_VARIANT +#include +#include + #include #include -#include -#include -class Variant -{ -public: +class Variant { + public: static std::string dateFormat; static bool searchCaseSensitive; static bool searchUsingRegex; static bool isoEnabled; - enum type {type_boolean, type_integer, type_real, type_string, type_date, type_duration}; + enum type { type_boolean, type_integer, type_real, type_string, type_date, type_duration }; - Variant () = default; - Variant (const Variant&); - Variant (const bool); - Variant (const int); - Variant (const double); - Variant (const std::string&); - Variant (const char*); - Variant (const time_t, const enum type); + Variant() = default; + Variant(const Variant&); + Variant(const bool); + Variant(const int); + Variant(const double); + Variant(const std::string&); + Variant(const char*); + Variant(const time_t, const enum type); - void source (const std::string&); - const std::string& source () const; + void source(const std::string&); + const std::string& source() const; - Variant& operator= (const Variant&); + Variant& operator=(const Variant&); - bool operator&& (const Variant&) const; - bool operator|| (const Variant&) const; - bool operator_xor (const Variant&) const; - bool operator< (const Variant&) const; - bool operator<= (const Variant&) const; - bool operator> (const Variant&) const; - bool operator>= (const Variant&) const; - bool operator== (const Variant&) const; - bool operator!= (const Variant&) const; - bool operator_match (const Variant&, const Task&) const; - bool operator_nomatch (const Variant&, const Task&) const; - bool operator_partial (const Variant&) const; - bool operator_nopartial (const Variant&) const; - bool operator_hastag (const Variant&, const Task&) const; - bool operator_notag (const Variant&, const Task&) const; - bool operator! () const; + bool operator&&(const Variant&) const; + bool operator||(const Variant&) const; + bool operator_xor(const Variant&) const; + bool operator<(const Variant&) const; + bool operator<=(const Variant&) const; + bool operator>(const Variant&) const; + bool operator>=(const Variant&) const; + bool operator==(const Variant&) const; + bool operator!=(const Variant&) const; + bool operator_match(const Variant&, const Task&) const; + bool operator_nomatch(const Variant&, const Task&) const; + bool operator_partial(const Variant&) const; + bool operator_nopartial(const Variant&) const; + bool operator_hastag(const Variant&, const Task&) const; + bool operator_notag(const Variant&, const Task&) const; + bool operator!() const; - Variant& operator^= (const Variant&); - Variant operator^ (const Variant&) const; + Variant& operator^=(const Variant&); + Variant operator^(const Variant&) const; - Variant& operator-= (const Variant&); - Variant operator- (const Variant&) const; + Variant& operator-=(const Variant&); + Variant operator-(const Variant&) const; - Variant& operator+= (const Variant&); - Variant operator+ (const Variant&) const; + Variant& operator+=(const Variant&); + Variant operator+(const Variant&) const; - Variant& operator*= (const Variant&); - Variant operator* (const Variant&) const; + Variant& operator*=(const Variant&); + Variant operator*(const Variant&) const; - Variant& operator/= (const Variant&); - Variant operator/ (const Variant&) const; + Variant& operator/=(const Variant&); + Variant operator/(const Variant&) const; - Variant& operator%= (const Variant&); - Variant operator% (const Variant&) const; + Variant& operator%=(const Variant&); + Variant operator%(const Variant&) const; - operator std::string () const; - void sqrt (); + operator std::string() const; + void sqrt(); - void cast (const enum type); - int type (); - bool trivial () const; + void cast(const enum type); + int type(); + bool trivial() const; - bool get_bool () const; - long long get_integer () const; - double get_real () const; - const std::string& get_string () const; - time_t get_date () const; - time_t get_duration () const; + bool get_bool() const; + long long get_integer() const; + double get_real() const; + const std::string& get_string() const; + time_t get_date() const; + time_t get_duration() const; -private: - enum type _type {type_boolean}; - bool _bool {false}; - long long _integer {0}; - double _real {0.0}; - std::string _string {""}; - time_t _date {0}; - time_t _duration {0}; + private: + enum type _type { type_boolean }; + bool _bool{false}; + long long _integer{0}; + double _real{0.0}; + std::string _string{""}; + time_t _date{0}; + time_t _duration{0}; - std::string _source {""}; + std::string _source{""}; }; #endif diff --git a/src/Version.cpp b/src/Version.cpp index 8d79c6816..e1633f86c 100644 --- a/src/Version.cpp +++ b/src/Version.cpp @@ -67,38 +67,32 @@ bool Version::is_valid() const { return major >= 0; } //////////////////////////////////////////////////////////////////////////////// bool Version::operator<(const Version &other) const { - return std::tie(major, minor, patch) < - std::tie(other.major, other.minor, other.patch); + return std::tie(major, minor, patch) < std::tie(other.major, other.minor, other.patch); } //////////////////////////////////////////////////////////////////////////////// bool Version::operator<=(const Version &other) const { - return std::tie(major, minor, patch) <= - std::tie(other.major, other.minor, other.patch); + return std::tie(major, minor, patch) <= std::tie(other.major, other.minor, other.patch); } //////////////////////////////////////////////////////////////////////////////// bool Version::operator>(const Version &other) const { - return std::tie(major, minor, patch) > - std::tie(other.major, other.minor, other.patch); + return std::tie(major, minor, patch) > std::tie(other.major, other.minor, other.patch); } //////////////////////////////////////////////////////////////////////////////// bool Version::operator>=(const Version &other) const { - return std::tie(major, minor, patch) >= - std::tie(other.major, other.minor, other.patch); + return std::tie(major, minor, patch) >= std::tie(other.major, other.minor, other.patch); } //////////////////////////////////////////////////////////////////////////////// bool Version::operator==(const Version &other) const { - return std::tie(major, minor, patch) == - std::tie(other.major, other.minor, other.patch); + return std::tie(major, minor, patch) == std::tie(other.major, other.minor, other.patch); } //////////////////////////////////////////////////////////////////////////////// bool Version::operator!=(const Version &other) const { - return std::tie(major, minor, patch) != - std::tie(other.major, other.minor, other.patch); + return std::tie(major, minor, patch) != std::tie(other.major, other.minor, other.patch); } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/Version.h b/src/Version.h index 2c96d61e7..03b81d2ad 100644 --- a/src/Version.h +++ b/src/Version.h @@ -31,7 +31,7 @@ // A utility class for handling Taskwarrior versions. class Version { -public: + public: // Parse a version from a string. This must be of the format // digits.digits.digits. explicit Version(std::string version); @@ -60,9 +60,9 @@ public: // Convert back to a string. operator std::string() const; - friend std::ostream& operator<<(std::ostream& os, const Version& version); + friend std::ostream &operator<<(std::ostream &os, const Version &version); -private: + private: int major = -1; int minor = -1; int patch = -1; diff --git a/src/ViewTask.cpp b/src/ViewTask.cpp index 791316002..ce4cbaa2a 100644 --- a/src/ViewTask.cpp +++ b/src/ViewTask.cpp @@ -27,42 +27,39 @@ #include // cmake.h include header must come first -#include -#include #include +#include #include -#include -#include #include +#include +#include + +#include //////////////////////////////////////////////////////////////////////////////// -ViewTask::ViewTask () -: _width (0) -, _left_margin (0) -, _header (0) -, _sort_header (0) -, _odd (0) -, _even (0) -, _intra_padding (1) -, _intra_odd (0) -, _intra_even (0) -, _extra_padding (0) -, _extra_odd (0) -, _extra_even (0) -, _truncate_lines (0) -, _truncate_rows (0) -, _lines (0) -, _rows (0) -{ -} +ViewTask::ViewTask() + : _width(0), + _left_margin(0), + _header(0), + _sort_header(0), + _odd(0), + _even(0), + _intra_padding(1), + _intra_odd(0), + _intra_even(0), + _extra_padding(0), + _extra_odd(0), + _extra_even(0), + _truncate_lines(0), + _truncate_rows(0), + _lines(0), + _rows(0) {} //////////////////////////////////////////////////////////////////////////////// -ViewTask::~ViewTask () -{ - for (auto& col : _columns) - delete col; +ViewTask::~ViewTask() { + for (auto& col : _columns) delete col; - _columns.clear (); + _columns.clear(); } //////////////////////////////////////////////////////////////////////////////// @@ -108,64 +105,55 @@ ViewTask::~ViewTask () // the larger fields. If the widest field is W0, and the second widest // field is W1, then a solution may be achievable by reducing W0 --> W1. // -std::string ViewTask::render (std::vector & data, std::vector & sequence) -{ +std::string ViewTask::render(std::vector& data, std::vector& sequence) { Timer timer; - bool const obfuscate = Context::getContext ().config.getBoolean ("obfuscate"); - bool const print_empty_columns = Context::getContext ().config.getBoolean ("print.empty.columns"); - std::vector nonempty_columns; - std::vector nonempty_sort; + bool const obfuscate = Context::getContext().config.getBoolean("obfuscate"); + bool const print_empty_columns = Context::getContext().config.getBoolean("print.empty.columns"); + std::vector nonempty_columns; + std::vector nonempty_sort; // Determine minimal, ideal column widths. - std::vector minimal; - std::vector ideal; + std::vector minimal; + std::vector ideal; - for (unsigned int i = 0; i < _columns.size (); ++i) - { + for (unsigned int i = 0; i < _columns.size(); ++i) { // Headers factor in to width calculations. unsigned int global_min = 0; unsigned int global_ideal = global_min; - for (unsigned int s = 0; s < sequence.size (); ++s) - { - if ((int)s >= _truncate_lines && _truncate_lines != 0) - break; + for (unsigned int s = 0; s < sequence.size(); ++s) { + if ((int)s >= _truncate_lines && _truncate_lines != 0) break; - if ((int)s >= _truncate_rows && _truncate_rows != 0) - break; + if ((int)s >= _truncate_rows && _truncate_rows != 0) break; // Determine minimum and ideal width for this column. unsigned int min = 0; unsigned int ideal = 0; - _columns[i]->measure (data[sequence[s]], min, ideal); + _columns[i]->measure(data[sequence[s]], min, ideal); - if (min > global_min) global_min = min; + if (min > global_min) global_min = min; if (ideal > global_ideal) global_ideal = ideal; // If a fixed-width column was just measured, there is no point repeating // the measurement for all tasks. - if (_columns[i]->is_fixed_width ()) - break; + if (_columns[i]->is_fixed_width()) break; } - if (print_empty_columns || global_min != 0) - { - unsigned int label_length = utf8_width (_columns[i]->label ()); - if (label_length > global_min) global_min = label_length; + if (print_empty_columns || global_min != 0) { + unsigned int label_length = utf8_width(_columns[i]->label()); + if (label_length > global_min) global_min = label_length; if (label_length > global_ideal) global_ideal = label_length; - minimal.push_back (global_min); - ideal.push_back (global_ideal); + minimal.push_back(global_min); + ideal.push_back(global_ideal); } - if (! print_empty_columns) - { - if (global_min != 0) // Column is nonempty + if (!print_empty_columns) { + if (global_min != 0) // Column is nonempty { - nonempty_columns.push_back (_columns[i]); - nonempty_sort.push_back (_sort[i]); - } - else // Column is empty, drop it + nonempty_columns.push_back(_columns[i]); + nonempty_sort.push_back(_sort[i]); + } else // Column is empty, drop it { // Note: This is safe to do because we set _columns = nonempty_columns // after iteration over _columns is finished. @@ -174,51 +162,40 @@ std::string ViewTask::render (std::vector & data, std::vector & seque } } - if (! print_empty_columns) - { + if (!print_empty_columns) { _columns = nonempty_columns; _sort = nonempty_sort; } - int all_extra = _left_margin - + (2 * _extra_padding) - + ((_columns.size () - 1) * _intra_padding); + int all_extra = _left_margin + (2 * _extra_padding) + ((_columns.size() - 1) * _intra_padding); // Sum the widths. - int sum_minimal = std::accumulate (minimal.begin (), minimal.end (), 0); - int sum_ideal = std::accumulate (ideal.begin (), ideal.end (), 0); + int sum_minimal = std::accumulate(minimal.begin(), minimal.end(), 0); + int sum_ideal = std::accumulate(ideal.begin(), ideal.end(), 0); // Calculate final column widths. int overage = _width - sum_minimal - all_extra; - Context::getContext ().debug (format ("ViewTask::render min={1} ideal={2} overage={3} width={4}", - sum_minimal + all_extra, - sum_ideal + all_extra, - overage, - _width)); + Context::getContext().debug(format("ViewTask::render min={1} ideal={2} overage={3} width={4}", + sum_minimal + all_extra, sum_ideal + all_extra, overage, + _width)); - std::vector widths; + std::vector widths; // Ideal case. Everything fits. - if (_width == 0 || sum_ideal + all_extra <= _width) - { + if (_width == 0 || sum_ideal + all_extra <= _width) { widths = ideal; } // Not enough for minimum. Decrease certain columns. - else if (overage < 0) - { + else if (overage < 0) { // Determine which columns are the longest. unsigned int longest = 0; unsigned int second_longest = 0; - for (unsigned int j = 0; j < minimal.size(); j++) - { - if (minimal[j] > minimal[longest]) - { + for (unsigned int j = 0; j < minimal.size(); j++) { + if (minimal[j] > minimal[longest]) { second_longest = longest; longest = j; - } - else if (minimal[j] > minimal[second_longest]) - { + } else if (minimal[j] > minimal[second_longest]) { second_longest = j; } } @@ -226,53 +203,46 @@ std::string ViewTask::render (std::vector & data, std::vector & seque // Case 1: Shortening longest column still keeps it longest. Let it bear // all the shortening. widths = minimal; - if (minimal[longest] + overage >= minimal[second_longest]) - widths[longest] += overage; + if (minimal[longest] + overage >= minimal[second_longest]) widths[longest] += overage; // Case 2: Shorten the longest column to second longest length. Try to // split shortening them evenly. - else - { + else { int decrease = minimal[second_longest] - minimal[longest]; widths[longest] += decrease; overage = overage - decrease; // Attempt to decrease the two longest columns (at most to two characters) - if (-overage <= widths[longest] + widths[second_longest] - 4) - { + if (-overage <= widths[longest] + widths[second_longest] - 4) { // Compute half of the overage, rounding up int half_overage = overage / 2 + overage % 2; // Decrease both larges columns by this amount widths[longest] += half_overage; widths[second_longest] += half_overage; - } - else + } else // If reducing two of the longest solumns to 2 characters is not sufficient, then give up. - Context::getContext ().error (format ("The report has a minimum width of {1} and does not fit in the available width of {2}.", sum_minimal + all_extra, _width)); + Context::getContext().error(format( + "The report has a minimum width of {1} and does not fit in the available width of {2}.", + sum_minimal + all_extra, _width)); } } // Perfect minimal width. - else if (overage == 0) - { + else if (overage == 0) { widths = minimal; } // Extra space to share. - else if (overage > 0) - { + else if (overage > 0) { widths = minimal; // Spread 'overage' among columns where width[i] < ideal[i] bool needed = true; - while (overage && needed) - { + while (overage && needed) { needed = false; - for (unsigned int i = 0; i < _columns.size () && overage; ++i) - { - if (widths[i] < ideal[i]) - { + for (unsigned int i = 0; i < _columns.size() && overage; ++i) { + if (widths[i] < ideal[i]) { ++widths[i]; --overage; needed = true; @@ -283,39 +253,34 @@ std::string ViewTask::render (std::vector & data, std::vector & seque // Compose column headers. unsigned int max_lines = 0; - std::vector > headers; - for (unsigned int c = 0; c < _columns.size (); ++c) - { - headers.emplace_back (); - _columns[c]->renderHeader (headers[c], widths[c], _sort[c] ? _sort_header : _header); + std::vector> headers; + for (unsigned int c = 0; c < _columns.size(); ++c) { + headers.emplace_back(); + _columns[c]->renderHeader(headers[c], widths[c], _sort[c] ? _sort_header : _header); - if (headers[c].size () > max_lines) - max_lines = headers[c].size (); + if (headers[c].size() > max_lines) max_lines = headers[c].size(); } // Render column headers. - std::string left_margin = std::string (_left_margin, ' '); - std::string extra = std::string (_extra_padding, ' '); - std::string intra = std::string (_intra_padding, ' '); + std::string left_margin = std::string(_left_margin, ' '); + std::string extra = std::string(_extra_padding, ' '); + std::string intra = std::string(_intra_padding, ' '); - std::string extra_odd = Context::getContext ().color () ? _extra_odd.colorize (extra) : extra; - std::string extra_even = Context::getContext ().color () ? _extra_even.colorize (extra) : extra; - std::string intra_odd = Context::getContext ().color () ? _intra_odd.colorize (intra) : intra; - std::string intra_even = Context::getContext ().color () ? _intra_even.colorize (intra) : intra; + std::string extra_odd = Context::getContext().color() ? _extra_odd.colorize(extra) : extra; + std::string extra_even = Context::getContext().color() ? _extra_even.colorize(extra) : extra; + std::string intra_odd = Context::getContext().color() ? _intra_odd.colorize(intra) : intra; + std::string intra_even = Context::getContext().color() ? _intra_even.colorize(intra) : intra; std::string out; _lines = 0; - for (unsigned int i = 0; i < max_lines; ++i) - { + for (unsigned int i = 0; i < max_lines; ++i) { out += left_margin + extra; - for (unsigned int c = 0; c < _columns.size (); ++c) - { - if (c) - out += intra; + for (unsigned int c = 0; c < _columns.size(); ++c) { + if (c) out += intra; - if (headers[c].size () < max_lines - i) - out += _header.colorize (std::string (widths[c], ' ')); + if (headers[c].size() < max_lines - i) + out += _header.colorize(std::string(widths[c], ' ')); else out += headers[c][i]; } @@ -323,60 +288,50 @@ std::string ViewTask::render (std::vector & data, std::vector & seque out += extra; // Trim right. - out.erase (out.find_last_not_of (' ') + 1); + out.erase(out.find_last_not_of(' ') + 1); out += "\n"; // Stop if the line limit is exceeded. - if (++_lines >= _truncate_lines && _truncate_lines != 0) - { - Context::getContext ().time_render_us += timer.total_us (); + if (++_lines >= _truncate_lines && _truncate_lines != 0) { + Context::getContext().time_render_us += timer.total_us(); return out; } } // Compose, render columns, in sequence. _rows = 0; - std::vector > cells; - for (unsigned int s = 0; s < sequence.size (); ++s) - { + std::vector> cells; + for (unsigned int s = 0; s < sequence.size(); ++s) { max_lines = 0; // Apply color rules to task. Color rule_color; - autoColorize (data[sequence[s]], rule_color); + autoColorize(data[sequence[s]], rule_color); // Alternate rows based on |s % 2| bool odd = (s % 2) ? true : false; Color row_color; - if (Context::getContext ().color ()) - { + if (Context::getContext().color()) { row_color = odd ? _odd : _even; - row_color.blend (rule_color); + row_color.blend(rule_color); } - for (unsigned int c = 0; c < _columns.size (); ++c) - { - cells.emplace_back (); - _columns[c]->render (cells[c], data[sequence[s]], widths[c], row_color); + for (unsigned int c = 0; c < _columns.size(); ++c) { + cells.emplace_back(); + _columns[c]->render(cells[c], data[sequence[s]], widths[c], row_color); - if (cells[c].size () > max_lines) - max_lines = cells[c].size (); + if (cells[c].size() > max_lines) max_lines = cells[c].size(); if (obfuscate) - if (_columns[c]->type () == "string") - for (auto& line : cells[c]) - line = obfuscateText (line); + if (_columns[c]->type() == "string") + for (auto& line : cells[c]) line = obfuscateText(line); } // Listing breaks are simply blank lines inserted when a column value // changes. - if (s > 0 && - _breaks.size () > 0) - { - for (const auto& b : _breaks) - { - if (data[sequence[s - 1]].get (b) != data[sequence[s]].get (b)) - { + if (s > 0 && _breaks.size() > 0) { + for (const auto& b : _breaks) { + if (data[sequence[s - 1]].get(b) != data[sequence[s]].get(b)) { out += "\n"; ++_lines; @@ -386,51 +341,46 @@ std::string ViewTask::render (std::vector & data, std::vector & seque } } - for (unsigned int i = 0; i < max_lines; ++i) - { + for (unsigned int i = 0; i < max_lines; ++i) { out += left_margin + (odd ? extra_odd : extra_even); - for (unsigned int c = 0; c < _columns.size (); ++c) - { - if (c) - { - if (row_color.nontrivial ()) - row_color._colorize (out, intra); + for (unsigned int c = 0; c < _columns.size(); ++c) { + if (c) { + if (row_color.nontrivial()) + row_color._colorize(out, intra); else out += (odd ? intra_odd : intra_even); } - if (i < cells[c].size ()) + if (i < cells[c].size()) out += cells[c][i]; else - row_color._colorize (out, std::string (widths[c], ' ')); + row_color._colorize(out, std::string(widths[c], ' ')); } out += (odd ? extra_odd : extra_even); // Trim right. - out.erase (out.find_last_not_of (' ') + 1); + out.erase(out.find_last_not_of(' ') + 1); out += "\n"; // Stop if the line limit is exceeded. - if (++_lines >= _truncate_lines && _truncate_lines != 0) - { - Context::getContext ().time_render_us += timer.total_us (); + if (++_lines >= _truncate_lines && _truncate_lines != 0) { + Context::getContext().time_render_us += timer.total_us(); return out; } } - cells.clear (); + cells.clear(); // Stop if the row limit is exceeded. - if (++_rows >= _truncate_rows && _truncate_rows != 0) - { - Context::getContext ().time_render_us += timer.total_us (); + if (++_rows >= _truncate_rows && _truncate_rows != 0) { + Context::getContext().time_render_us += timer.total_us(); return out; } } - Context::getContext ().time_render_us += timer.total_us (); + Context::getContext().time_render_us += timer.total_us(); return out; } diff --git a/src/ViewTask.h b/src/ViewTask.h index e71bc95bf..b606ec992 100644 --- a/src/ViewTask.h +++ b/src/ViewTask.h @@ -27,63 +27,68 @@ #ifndef INCLUDED_VIEWTASK #define INCLUDED_VIEWTASK -#include -#include -#include #include #include +#include -class ViewTask -{ -public: - ViewTask (); - ~ViewTask (); +#include +#include + +class ViewTask { + public: + ViewTask(); + ~ViewTask(); // View specifications. - void add (Column* column, bool sort = false) { _columns.push_back (column); _sort.push_back (sort); } - void width (int width) { _width = width; } - void leftMargin (int margin) { _left_margin = margin; } - void colorHeader (Color& c) { _header = c; if (!_sort_header) _sort_header = c; } - void colorSortHeader (Color& c) { _sort_header = c; } - void colorOdd (Color& c) { _odd = c; } - void colorEven (Color& c) { _even = c; } - void intraPadding (int padding) { _intra_padding = padding; } - void intraColorOdd (Color& c) { _intra_odd = c; } - void intraColorEven (Color& c) { _intra_even = c; } - void extraPadding (int padding) { _extra_padding = padding; } - void extraColorOdd (Color& c) { _extra_odd = c; } - void extraColorEven (Color& c) { _extra_even = c; } - void truncateLines (int n) { _truncate_lines = n; } - void truncateRows (int n) { _truncate_rows = n; } - void addBreak (const std::string& attr) { _breaks.push_back (attr); } - int lines () { return _lines; } - int rows () { return _rows; } + void add(Column* column, bool sort = false) { + _columns.push_back(column); + _sort.push_back(sort); + } + void width(int width) { _width = width; } + void leftMargin(int margin) { _left_margin = margin; } + void colorHeader(Color& c) { + _header = c; + if (!_sort_header) _sort_header = c; + } + void colorSortHeader(Color& c) { _sort_header = c; } + void colorOdd(Color& c) { _odd = c; } + void colorEven(Color& c) { _even = c; } + void intraPadding(int padding) { _intra_padding = padding; } + void intraColorOdd(Color& c) { _intra_odd = c; } + void intraColorEven(Color& c) { _intra_even = c; } + void extraPadding(int padding) { _extra_padding = padding; } + void extraColorOdd(Color& c) { _extra_odd = c; } + void extraColorEven(Color& c) { _extra_even = c; } + void truncateLines(int n) { _truncate_lines = n; } + void truncateRows(int n) { _truncate_rows = n; } + void addBreak(const std::string& attr) { _breaks.push_back(attr); } + int lines() { return _lines; } + int rows() { return _rows; } // View rendering. - std::string render (std::vector &, std::vector &); + std::string render(std::vector&, std::vector&); -private: - std::vector _columns; - std::vector _sort; - std::vector _breaks; - int _width; - int _left_margin; - Color _header; - Color _sort_header; - Color _odd; - Color _even; - int _intra_padding; - Color _intra_odd; - Color _intra_even; - int _extra_padding; - Color _extra_odd; - Color _extra_even; - int _truncate_lines; - int _truncate_rows; - int _lines; - int _rows; + private: + std::vector _columns; + std::vector _sort; + std::vector _breaks; + int _width; + int _left_margin; + Color _header; + Color _sort_header; + Color _odd; + Color _even; + int _intra_padding; + Color _intra_odd; + Color _intra_even; + int _extra_padding; + Color _extra_odd; + Color _extra_even; + int _truncate_lines; + int _truncate_rows; + int _lines; + int _rows; }; #endif //////////////////////////////////////////////////////////////////////////////// - diff --git a/src/calc.cpp b/src/calc.cpp index af852d64b..4ff490abd 100644 --- a/src/calc.cpp +++ b/src/calc.cpp @@ -27,57 +27,53 @@ #include // cmake.h include header must come first -#include -#include -#include -#include -#include #include -#include #include #include -#include +#include +#include #include +#include +#include +#include + +#include +#include //////////////////////////////////////////////////////////////////////////////// // Constants. -bool get (const std::string&, Variant&) -{ -/* - // An example, although a bad one because this is supported by default. - if (name == "pi") {value = Variant (3.14159165); return true;} -*/ +bool get(const std::string&, Variant&) { + /* + // An example, although a bad one because this is supported by default. + if (name == "pi") {value = Variant (3.14159165); return true;} + */ return false; } //////////////////////////////////////////////////////////////////////////////// -int main (int argc, char** argv) -{ +int main(int argc, char** argv) { int status = 0; - try - { + try { Context globalContext; - Context::setContext (&globalContext); + Context::setContext(&globalContext); // Same operating parameters as Context::staticInitialization. - Datetime::standaloneDateEnabled = false; - Datetime::standaloneTimeEnabled = false; + Datetime::standaloneDateEnabled = false; + Datetime::standaloneTimeEnabled = false; Duration::standaloneSecondsEnabled = false; - bool infix {true}; + bool infix{true}; // Add a source for constants. Eval e; - e.addSource (get); + e.addSource(get); // Combine all the arguments into one expression string. std::string expression; - for (int i = 1; i < argc; i++) - { - if (!strcmp (argv[i], "-h") || ! strcmp (argv[i], "--help")) - { + for (int i = 1; i < argc; i++) { + if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { std::cout << '\n' << "Usage: " << argv[0] << " [options] ''\n" << '\n' @@ -87,56 +83,47 @@ int main (int argc, char** argv) << " -i|--infix Infix expression (default)\n" << " -p|--postfix Postfix expression\n" << '\n'; - exit (1); - } - else if (!strcmp (argv[i], "-v") || !strcmp (argv[i], "--version")) - { + exit(1); + } else if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--version")) { std::cout << '\n' - << format ("calc {1} built for ", VERSION) - << osName () + << format("calc {1} built for ", VERSION) << osName() << '\n' + << "Copyright (C) 2006 - 2021 T. Babej, P. Beckingham, F. Hernandez." << '\n' << '\n' - << "Copyright (C) 2006 - 2021 T. Babej, P. Beckingham, F. Hernandez." - << '\n' - << '\n' - << "Taskwarrior may be copied only under the terms of the MIT license, which may be found in the Taskwarrior source kit." + << "Taskwarrior may be copied only under the terms of the MIT license, which may " + "be found in the Taskwarrior source kit." << '\n' << '\n'; - exit (1); - } - else if (!strcmp (argv[i], "-d") || !strcmp (argv[i], "--debug")) - e.debug (true); - else if (!strcmp (argv[i], "-i") || !strcmp (argv[i], "--infix")) + exit(1); + } else if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) + e.debug(true); + else if (!strcmp(argv[i], "-i") || !strcmp(argv[i], "--infix")) infix = true; - else if (!strcmp (argv[i], "-p") || !strcmp (argv[i], "--postfix")) + else if (!strcmp(argv[i], "-p") || !strcmp(argv[i], "--postfix")) infix = false; else - expression += std::string (argv[i]) + ' '; + expression += std::string(argv[i]) + ' '; } Variant result; if (infix) - e.evaluateInfixExpression (expression, result); + e.evaluateInfixExpression(expression, result); else - e.evaluatePostfixExpression (expression, result); + e.evaluatePostfixExpression(expression, result); // Show any debug output. - for (const auto& i : Context::getContext ().debugMessages) - std::cout << i << '\n'; + for (const auto& i : Context::getContext().debugMessages) std::cout << i << '\n'; // Show the result in string form. - std::cout << (std::string) result - << '\n'; + std::cout << (std::string)result << '\n'; } - catch (const std::string& error) - { + catch (const std::string& error) { std::cerr << error << '\n'; status = -1; } - catch (...) - { + catch (...) { std::cerr << "Unknown error occured. Oops.\n"; status = -2; } diff --git a/src/columns/ColDepends.cpp b/src/columns/ColDepends.cpp index 1bd01a72b..d0c77d0b3 100644 --- a/src/columns/ColDepends.cpp +++ b/src/columns/ColDepends.cpp @@ -28,30 +28,26 @@ // cmake.h include header must come first #include -#include #include -#include #include -#include #include -#include +#include #include +#include +#include + +#include #include #define STRING_COLUMN_LABEL_DEP "Depends" //////////////////////////////////////////////////////////////////////////////// -ColumnDepends::ColumnDepends () -{ - _name = "depends"; - _style = "list"; - _label = STRING_COLUMN_LABEL_DEP; - _styles = {"list", - "count", - "indicator"}; - _examples = {"1 2 10", - "[3]", - Context::getContext ().config.get ("dependency.indicator")}; +ColumnDepends::ColumnDepends() { + _name = "depends"; + _style = "list"; + _label = STRING_COLUMN_LABEL_DEP; + _styles = {"list", "count", "indicator"}; + _examples = {"1 2 10", "[3]", Context::getContext().config.get("dependency.indicator")}; _hyphenate = false; } @@ -59,156 +55,131 @@ ColumnDepends::ColumnDepends () //////////////////////////////////////////////////////////////////////////////// // Overriden so that style <----> label are linked. // Note that you can not determine which gets called first. -void ColumnDepends::setStyle (const std::string& value) -{ - Column::setStyle (value); +void ColumnDepends::setStyle(const std::string& value) { + Column::setStyle(value); - if (_style == "indicator" && _label == STRING_COLUMN_LABEL_DEP) _label = _label.substr (0, Context::getContext ().config.get ("dependency.indicator").length ()); - else if (_style == "count" && _label == STRING_COLUMN_LABEL_DEP) _label = "Dep"; + if (_style == "indicator" && _label == STRING_COLUMN_LABEL_DEP) + _label = _label.substr(0, Context::getContext().config.get("dependency.indicator").length()); + else if (_style == "count" && _label == STRING_COLUMN_LABEL_DEP) + _label = "Dep"; } //////////////////////////////////////////////////////////////////////////////// // Set the minimum and maximum widths for the value. -void ColumnDepends::measure (Task& task, unsigned int& minimum, unsigned int& maximum) -{ +void ColumnDepends::measure(Task& task, unsigned int& minimum, unsigned int& maximum) { minimum = maximum = 0; - auto deptasks = task.getDependencyTasks (); + auto deptasks = task.getDependencyTasks(); - if (deptasks.size () > 0) - { - if (_style == "indicator") - { - minimum = maximum = utf8_width (Context::getContext ().config.get ("dependency.indicator")); + if (deptasks.size() > 0) { + if (_style == "indicator") { + minimum = maximum = utf8_width(Context::getContext().config.get("dependency.indicator")); } - else if (_style == "count") - { - minimum = maximum = 2 + format ((int) deptasks.size ()).length (); + else if (_style == "count") { + minimum = maximum = 2 + format((int)deptasks.size()).length(); } - else if (_style == "default" || - _style == "list") - { + else if (_style == "default" || _style == "list") { minimum = maximum = 0; - std::vector blocking_ids; + std::vector blocking_ids; blocking_ids.reserve(deptasks.size()); - for (auto& i : deptasks) - blocking_ids.push_back (i.id); + for (auto& i : deptasks) blocking_ids.push_back(i.id); - auto all = join (" ", blocking_ids); - maximum = all.length (); + auto all = join(" ", blocking_ids); + maximum = all.length(); unsigned int length; - for (auto& i : deptasks) - { - length = format (i.id).length (); - if (length > minimum) - minimum = length; + for (auto& i : deptasks) { + length = format(i.id).length(); + if (length > minimum) minimum = length; } } } } //////////////////////////////////////////////////////////////////////////////// -void ColumnDepends::render ( - std::vector & lines, - Task& task, - int width, - Color& color) -{ - auto deptasks = task.getDependencyTasks (); +void ColumnDepends::render(std::vector& lines, Task& task, int width, Color& color) { + auto deptasks = task.getDependencyTasks(); - if (deptasks.size () > 0) - { - if (_style == "indicator") - { - renderStringRight (lines, width, color, Context::getContext ().config.get ("dependency.indicator")); + if (deptasks.size() > 0) { + if (_style == "indicator") { + renderStringRight(lines, width, color, + Context::getContext().config.get("dependency.indicator")); } - else if (_style == "count") - { - renderStringRight (lines, width, color, '[' + format (static_cast (deptasks.size ())) + ']'); + else if (_style == "count") { + renderStringRight(lines, width, color, '[' + format(static_cast(deptasks.size())) + ']'); } - else if (_style == "default" || - _style == "list") - { - std::vector blocking_ids; + else if (_style == "default" || _style == "list") { + std::vector blocking_ids; blocking_ids.reserve(deptasks.size()); - for (const auto& t : deptasks) - blocking_ids.push_back (t.id); + for (const auto& t : deptasks) blocking_ids.push_back(t.id); - auto combined = join (" ", blocking_ids); + auto combined = join(" ", blocking_ids); - std::vector all; - wrapText (all, combined, width, _hyphenate); + std::vector all; + wrapText(all, combined, width, _hyphenate); - for (const auto& i : all) - renderStringLeft (lines, width, color, i); + for (const auto& i : all) renderStringLeft(lines, width, color, i); } } } //////////////////////////////////////////////////////////////////////////////// -void ColumnDepends::modify (Task& task, const std::string& value) -{ +void ColumnDepends::modify(Task& task, const std::string& value) { // Apply or remove dendencies in turn. - for (auto& dep : split (value, ',')) - { + for (auto& dep : split(value, ',')) { bool removal = false; - if (dep[0] == '-') - { + if (dep[0] == '-') { removal = true; dep = dep.substr(1); } - auto hyphen = dep.find ('-'); - long lower, upper; // For ID ranges - std::regex valid_uuid ("[a-f0-9]{8}([a-f0-9-]{4,28})?"); // TODO: Make more precise + auto hyphen = dep.find('-'); + long lower, upper; // For ID ranges + std::regex valid_uuid("[a-f0-9]{8}([a-f0-9-]{4,28})?"); // TODO: Make more precise // UUID - if (dep.length () >= 8 && std::regex_match (dep, valid_uuid)) - { - // Full UUID, can be added directly - if (dep.length () == 36) - if (removal) - task.removeDependency (dep); - else - task.addDependency (dep); + if (dep.length() >= 8 && std::regex_match(dep, valid_uuid)) { + // Full UUID, can be added directly + if (dep.length() == 36) + if (removal) + task.removeDependency(dep); + else + task.addDependency(dep); - // Short UUID, need to look up full form - else - { - Task loaded_task; - if (Context::getContext ().tdb2.get (dep, loaded_task)) - if (removal) - task.removeDependency (loaded_task.get ("uuid")); - else - task.addDependency (loaded_task.get ("uuid")); - else - throw format ("Dependency could not be set - task with UUID '{1}' does not exist.", dep); - } + // Short UUID, need to look up full form + else { + Task loaded_task; + if (Context::getContext().tdb2.get(dep, loaded_task)) + if (removal) + task.removeDependency(loaded_task.get("uuid")); + else + task.addDependency(loaded_task.get("uuid")); + else + throw format("Dependency could not be set - task with UUID '{1}' does not exist.", dep); + } } // ID range - else if (dep.find ('-') != std::string::npos && - extractLongInteger (dep.substr (0, hyphen), lower) && - extractLongInteger (dep.substr (hyphen + 1), upper)) - { + else if (dep.find('-') != std::string::npos && + extractLongInteger(dep.substr(0, hyphen), lower) && + extractLongInteger(dep.substr(hyphen + 1), upper)) { for (long i = lower; i <= upper; i++) - if (removal) - task.removeDependency (i); - else - task.addDependency (i); + if (removal) + task.removeDependency(i); + else + task.addDependency(i); } // Simple ID - else if (extractLongInteger (dep, lower)) + else if (extractLongInteger(dep, lower)) if (removal) - task.removeDependency (lower); + task.removeDependency(lower); else - task.addDependency (lower); + task.addDependency(lower); else - throw format ("Invalid dependency value: '{1}'", dep); + throw format("Invalid dependency value: '{1}'", dep); } } diff --git a/src/columns/ColDepends.h b/src/columns/ColDepends.h index bf36c5b03..ef79b8f06 100644 --- a/src/columns/ColDepends.h +++ b/src/columns/ColDepends.h @@ -29,17 +29,16 @@ #include -class ColumnDepends : public ColumnTypeString -{ -public: - ColumnDepends (); +class ColumnDepends : public ColumnTypeString { + public: + ColumnDepends(); - void setStyle (const std::string&); - void measure (Task&, unsigned int&, unsigned int&); - void render (std::vector &, Task&, int, Color&); - void modify (Task&, const std::string&); + void setStyle(const std::string&); + void measure(Task&, unsigned int&, unsigned int&); + void render(std::vector&, Task&, int, Color&); + void modify(Task&, const std::string&); -private: + private: bool _hyphenate; }; diff --git a/src/columns/ColDescription.cpp b/src/columns/ColDescription.cpp index b36661ff7..460465cff 100644 --- a/src/columns/ColDescription.cpp +++ b/src/columns/ColDescription.cpp @@ -28,233 +28,188 @@ // cmake.h include header must come first #include -#include #include #include -#include #include +#include +#include #include #include //////////////////////////////////////////////////////////////////////////////// -ColumnDescription::ColumnDescription () -{ - _name = "description"; - _style = "combined"; - _label = "Description"; +ColumnDescription::ColumnDescription() { + _name = "description"; + _style = "combined"; + _label = "Description"; _modifiable = true; - _styles = {"combined", - "desc", - "oneline", - "truncated", - "count", - "truncated_count"}; + _styles = {"combined", "desc", "oneline", "truncated", "count", "truncated_count"}; - _dateformat = Context::getContext ().config.get ("dateformat.annotation"); - if (_dateformat == "") - _dateformat = Context::getContext ().config.get ("dateformat"); + _dateformat = Context::getContext().config.get("dateformat.annotation"); + if (_dateformat == "") _dateformat = Context::getContext().config.get("dateformat"); - std::string t = Datetime ().toString (_dateformat); - std::string d = "Move your clothes down on to the lower peg"; + std::string t = Datetime().toString(_dateformat); + std::string d = "Move your clothes down on to the lower peg"; std::string a1 = "Immediately before your lunch"; std::string a2 = "If you are playing in the match this afternoon"; std::string a3 = "Before you write your letter home"; std::string a4 = "If you're not getting your hair cut"; - _examples = {d + "\n " + t + ' ' + a1 - + "\n " + t + ' ' + a2 - + "\n " + t + ' ' + a3 - + "\n " + t + ' ' + a4, - d, - d + ' ' + t + ' ' + a1 - + ' ' + t + ' ' + a2 - + ' ' + t + ' ' + a3 - + ' ' + t + ' ' + a4, - d.substr (0, 20) + "...", - d + " [4]", - d.substr (0, 20) + "... [4]"}; + _examples = { + d + "\n " + t + ' ' + a1 + "\n " + t + ' ' + a2 + "\n " + t + ' ' + a3 + "\n " + t + ' ' + + a4, + d, + d + ' ' + t + ' ' + a1 + ' ' + t + ' ' + a2 + ' ' + t + ' ' + a3 + ' ' + t + ' ' + a4, + d.substr(0, 20) + "...", + d + " [4]", + d.substr(0, 20) + "... [4]"}; - _hyphenate = Context::getContext ().config.getBoolean ("hyphenate"); + _hyphenate = Context::getContext().config.getBoolean("hyphenate"); - _indent = Context::getContext ().config.getInteger ("indent.annotation"); + _indent = Context::getContext().config.getInteger("indent.annotation"); } //////////////////////////////////////////////////////////////////////////////// // Set the minimum and maximum widths for the value. -void ColumnDescription::measure (Task& task, unsigned int& minimum, unsigned int& maximum) -{ - std::string description = task.get (_name); +void ColumnDescription::measure(Task& task, unsigned int& minimum, unsigned int& maximum) { + std::string description = task.get(_name); // The text // // ... - if (_style == "default" || - _style == "combined") - { - minimum = longestWord (description); - maximum = utf8_width (description); + if (_style == "default" || _style == "combined") { + minimum = longestWord(description); + maximum = utf8_width(description); - if (task.annotation_count) - { - unsigned int min_anno = _indent + Datetime::length (_dateformat); - if (min_anno > minimum) - minimum = min_anno; + if (task.annotation_count) { + unsigned int min_anno = _indent + Datetime::length(_dateformat); + if (min_anno > minimum) minimum = min_anno; - for (auto& i : task.getAnnotations ()) - { - unsigned int len = min_anno + 1 + utf8_width (i.second); - if (len > maximum) - maximum = len; + for (auto& i : task.getAnnotations()) { + unsigned int len = min_anno + 1 + utf8_width(i.second); + if (len > maximum) maximum = len; } } } // Just the text - else if (_style == "desc") - { - maximum = utf8_width (description); - minimum = longestWord (description); + else if (_style == "desc") { + maximum = utf8_width(description); + minimum = longestWord(description); } // The text ... - else if (_style == "oneline") - { - minimum = longestWord (description); - maximum = utf8_width (description); + else if (_style == "oneline") { + minimum = longestWord(description); + maximum = utf8_width(description); - if (task.annotation_count) - { - auto min_anno = Datetime::length (_dateformat); - for (auto& i : task.getAnnotations ()) - maximum += min_anno + 1 + utf8_width (i.second); + if (task.annotation_count) { + auto min_anno = Datetime::length(_dateformat); + for (auto& i : task.getAnnotations()) maximum += min_anno + 1 + utf8_width(i.second); } } // The te... - else if (_style == "truncated") - { + else if (_style == "truncated") { minimum = 4; - maximum = utf8_width (description); + maximum = utf8_width(description); } // The text [2] - else if (_style == "count") - { + else if (_style == "count") { // + ' ' + '[' + + ']' - maximum = utf8_width (description) + 1 + 1 + format (task.annotation_count).length () + 1; - minimum = longestWord (description); + maximum = utf8_width(description) + 1 + 1 + format(task.annotation_count).length() + 1; + minimum = longestWord(description); } // The te... [2] - else if (_style == "truncated_count") - { + else if (_style == "truncated_count") { minimum = 4; - maximum = utf8_width (description) + 1 + 1 + format (task.annotation_count).length () + 1; + maximum = utf8_width(description) + 1 + 1 + format(task.annotation_count).length() + 1; } } //////////////////////////////////////////////////////////////////////////////// -void ColumnDescription::render ( - std::vector & lines, - Task& task, - int width, - Color& color) -{ - std::string description = task.get (_name); +void ColumnDescription::render(std::vector& lines, Task& task, int width, + Color& color) { + std::string description = task.get(_name); // This is a description // // ... - if (_style == "default" || - _style == "combined") - { - if (task.annotation_count) - { - for (const auto& i : task.getAnnotations ()) - { - Datetime dt (strtoll (i.first.substr (11).c_str (), nullptr, 10)); - description += '\n' + std::string (_indent, ' ') + dt.toString (_dateformat) + ' ' + i.second; + if (_style == "default" || _style == "combined") { + if (task.annotation_count) { + for (const auto& i : task.getAnnotations()) { + Datetime dt(strtoll(i.first.substr(11).c_str(), nullptr, 10)); + description += '\n' + std::string(_indent, ' ') + dt.toString(_dateformat) + ' ' + i.second; } } - std::vector raw; - wrapText (raw, description, width, _hyphenate); + std::vector raw; + wrapText(raw, description, width, _hyphenate); - for (const auto& i : raw) - renderStringLeft (lines, width, color, i); + for (const auto& i : raw) renderStringLeft(lines, width, color, i); } // This is a description - else if (_style == "desc") - { - std::vector raw; - wrapText (raw, description, width, _hyphenate); + else if (_style == "desc") { + std::vector raw; + wrapText(raw, description, width, _hyphenate); - for (const auto& i : raw) - renderStringLeft (lines, width, color, i); + for (const auto& i : raw) renderStringLeft(lines, width, color, i); } // This is a description ... - else if (_style == "oneline") - { - if (task.annotation_count) - { - for (const auto& i : task.getAnnotations ()) - { - Datetime dt (strtoll (i.first.substr (11).c_str (), nullptr, 10)); - description += ' ' + dt.toString (_dateformat) + ' ' + i.second; + else if (_style == "oneline") { + if (task.annotation_count) { + for (const auto& i : task.getAnnotations()) { + Datetime dt(strtoll(i.first.substr(11).c_str(), nullptr, 10)); + description += ' ' + dt.toString(_dateformat) + ' ' + i.second; } } - std::vector raw; - wrapText (raw, description, width, _hyphenate); + std::vector raw; + wrapText(raw, description, width, _hyphenate); - for (const auto& i : raw) - renderStringLeft (lines, width, color, i); + for (const auto& i : raw) renderStringLeft(lines, width, color, i); } // This is a des... - else if (_style == "truncated") - { - int len = utf8_width (description); + else if (_style == "truncated") { + int len = utf8_width(description); if (len > width) - renderStringLeft (lines, width, color, description.substr (0, width - 3) + "..."); + renderStringLeft(lines, width, color, description.substr(0, width - 3) + "..."); else - renderStringLeft (lines, width, color, description); + renderStringLeft(lines, width, color, description); } // This is a description [2] - else if (_style == "count") - { - if (task.annotation_count) - description += " [" + format (task.annotation_count) + ']'; + else if (_style == "count") { + if (task.annotation_count) description += " [" + format(task.annotation_count) + ']'; - std::vector raw; - wrapText (raw, description, width, _hyphenate); + std::vector raw; + wrapText(raw, description, width, _hyphenate); - for (const auto& i : raw) - renderStringLeft (lines, width, color, i); + for (const auto& i : raw) renderStringLeft(lines, width, color, i); } // This is a des... [2] - else if (_style == "truncated_count") - { - int len = utf8_width (description); + else if (_style == "truncated_count") { + int len = utf8_width(description); std::string annos_count; int len_annos = 0; - if (task.annotation_count) - { - annos_count = " [" + format (task.annotation_count) + ']'; - len_annos = utf8_width (annos_count); + if (task.annotation_count) { + annos_count = " [" + format(task.annotation_count) + ']'; + len_annos = utf8_width(annos_count); len += len_annos; } if (len > width) - renderStringLeft (lines, width, color, description.substr (0, width - len_annos - 3) + "..." + annos_count); + renderStringLeft(lines, width, color, + description.substr(0, width - len_annos - 3) + "..." + annos_count); else - renderStringLeft (lines, width, color, description + annos_count); + renderStringLeft(lines, width, color, description + annos_count); } } diff --git a/src/columns/ColDescription.h b/src/columns/ColDescription.h index 0e1edb177..0178316a5 100644 --- a/src/columns/ColDescription.h +++ b/src/columns/ColDescription.h @@ -29,14 +29,13 @@ #include -class ColumnDescription : public ColumnTypeString -{ -public: - ColumnDescription (); - void measure (Task&, unsigned int&, unsigned int&); - void render (std::vector &, Task&, int, Color&); +class ColumnDescription : public ColumnTypeString { + public: + ColumnDescription(); + void measure(Task&, unsigned int&, unsigned int&); + void render(std::vector&, Task&, int, Color&); -private: + private: bool _hyphenate; std::string _dateformat; int _indent; diff --git a/src/columns/ColDue.cpp b/src/columns/ColDue.cpp index c1aee8ed3..40a23fab2 100644 --- a/src/columns/ColDue.cpp +++ b/src/columns/ColDue.cpp @@ -30,22 +30,19 @@ #include //////////////////////////////////////////////////////////////////////////////// -ColumnDue::ColumnDue () -{ - _name = "due"; +ColumnDue::ColumnDue() { + _name = "due"; _modifiable = true; - _label = "Due"; + _label = "Due"; } //////////////////////////////////////////////////////////////////////////////// // Overriden so that style <----> label are linked. // Note that you can not determine which gets called first. -void ColumnDue::setStyle (const std::string& value) -{ - Column::setStyle (value); +void ColumnDue::setStyle(const std::string& value) { + Column::setStyle(value); - if (_style == "countdown" && _label == "Due") - _label = "Count"; + if (_style == "countdown" && _label == "Due") _label = "Count"; } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/columns/ColDue.h b/src/columns/ColDue.h index 754ee06c7..4a35f378f 100644 --- a/src/columns/ColDue.h +++ b/src/columns/ColDue.h @@ -29,11 +29,10 @@ #include -class ColumnDue : public ColumnTypeDate -{ -public: - ColumnDue (); - void setStyle (const std::string&); +class ColumnDue : public ColumnTypeDate { + public: + ColumnDue(); + void setStyle(const std::string&); }; #endif diff --git a/src/columns/ColEnd.cpp b/src/columns/ColEnd.cpp index baddb8670..7b838a149 100644 --- a/src/columns/ColEnd.cpp +++ b/src/columns/ColEnd.cpp @@ -30,9 +30,8 @@ #include //////////////////////////////////////////////////////////////////////////////// -ColumnEnd::ColumnEnd () -{ - _name = "end"; +ColumnEnd::ColumnEnd() { + _name = "end"; _label = "Completed"; } diff --git a/src/columns/ColEnd.h b/src/columns/ColEnd.h index 387c16a43..4a19bbad6 100644 --- a/src/columns/ColEnd.h +++ b/src/columns/ColEnd.h @@ -29,10 +29,9 @@ #include -class ColumnEnd : public ColumnTypeDate -{ -public: - ColumnEnd (); +class ColumnEnd : public ColumnTypeDate { + public: + ColumnEnd(); }; #endif diff --git a/src/columns/ColEntry.cpp b/src/columns/ColEntry.cpp index 8068d710a..86670a1fd 100644 --- a/src/columns/ColEntry.cpp +++ b/src/columns/ColEntry.cpp @@ -30,23 +30,19 @@ #include //////////////////////////////////////////////////////////////////////////////// -ColumnEntry::ColumnEntry () -{ - _name = "entry"; +ColumnEntry::ColumnEntry() { + _name = "entry"; _modifiable = true; - _label = "Added"; + _label = "Added"; } //////////////////////////////////////////////////////////////////////////////// // Overriden so that style <----> label are linked. // Note that you can not determine which gets called first. -void ColumnEntry::setStyle (const std::string& value) -{ - Column::setStyle (value); +void ColumnEntry::setStyle(const std::string& value) { + Column::setStyle(value); - if (_style == "age" && - _label == "Added") - _label = "Age"; + if (_style == "age" && _label == "Added") _label = "Age"; } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/columns/ColEntry.h b/src/columns/ColEntry.h index ce734d1ab..72ae2ff7e 100644 --- a/src/columns/ColEntry.h +++ b/src/columns/ColEntry.h @@ -29,11 +29,10 @@ #include -class ColumnEntry : public ColumnTypeDate -{ -public: - ColumnEntry (); - void setStyle (const std::string&); +class ColumnEntry : public ColumnTypeDate { + public: + ColumnEntry(); + void setStyle(const std::string&); }; #endif diff --git a/src/columns/ColID.cpp b/src/columns/ColID.cpp index 9f66406e8..69f572434 100644 --- a/src/columns/ColID.cpp +++ b/src/columns/ColID.cpp @@ -28,48 +28,47 @@ // cmake.h include header must come first #include -#include #include +#include //////////////////////////////////////////////////////////////////////////////// -ColumnID::ColumnID () -{ - _name = "id"; - _style = "number"; - _label = "ID"; +ColumnID::ColumnID() { + _name = "id"; + _style = "number"; + _label = "ID"; _modifiable = false; - _styles = {"number"}; - _examples = {"123"}; + _styles = {"number"}; + _examples = {"123"}; } //////////////////////////////////////////////////////////////////////////////// // Set the minimum and maximum widths for the value. -void ColumnID::measure (Task& task, unsigned int& minimum, unsigned int& maximum) -{ +void ColumnID::measure(Task& task, unsigned int& minimum, unsigned int& maximum) { int length; - if (task.id < 10) length = 1; // Fast - else if (task.id < 100) length = 2; // Fast - else if (task.id < 1000) length = 3; // Fast - else if (task.id < 10000) length = 4; // Fast - else if (task.id < 100000) length = 5; // Fast - else length = 1 + (int) log10 ((double) task.id); // Slow + if (task.id < 10) + length = 1; // Fast + else if (task.id < 100) + length = 2; // Fast + else if (task.id < 1000) + length = 3; // Fast + else if (task.id < 10000) + length = 4; // Fast + else if (task.id < 100000) + length = 5; // Fast + else + length = 1 + (int)log10((double)task.id); // Slow minimum = maximum = length; } //////////////////////////////////////////////////////////////////////////////// -void ColumnID::render ( - std::vector & lines, - Task& task, - int width, - Color& color) -{ - // Completed and deleted tasks have no ID. +void ColumnID::render(std::vector& lines, Task& task, int width, Color& color) { + // Completed and deleted tasks have no ID. if (task.id) - renderInteger (lines, width, color, task.id); + renderInteger(lines, width, color, task.id); else - renderStringRight (lines, width, color, "-"); + renderStringRight(lines, width, color, "-"); } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/columns/ColID.h b/src/columns/ColID.h index fdec75db8..8279995a3 100644 --- a/src/columns/ColID.h +++ b/src/columns/ColID.h @@ -29,14 +29,13 @@ #include -class ColumnID : public ColumnTypeNumeric -{ -public: - ColumnID (); - void measure (Task&, unsigned int&, unsigned int&); - void render (std::vector &, Task&, int, Color&); +class ColumnID : public ColumnTypeNumeric { + public: + ColumnID(); + void measure(Task&, unsigned int&, unsigned int&); + void render(std::vector&, Task&, int, Color&); -private: + private: }; #endif diff --git a/src/columns/ColIMask.cpp b/src/columns/ColIMask.cpp index d4c79e249..067e8b85c 100644 --- a/src/columns/ColIMask.cpp +++ b/src/columns/ColIMask.cpp @@ -31,34 +31,25 @@ #include //////////////////////////////////////////////////////////////////////////////// -ColumnIMask::ColumnIMask () -{ - _name = "imask"; - _style = "number"; - _label = "Mask Index"; +ColumnIMask::ColumnIMask() { + _name = "imask"; + _style = "number"; + _label = "Mask Index"; _modifiable = false; - _styles = {"number"}; - _examples = {"12"}; + _styles = {"number"}; + _examples = {"12"}; } //////////////////////////////////////////////////////////////////////////////// // Set the minimum and maximum widths for the value. -void ColumnIMask::measure (Task& task, unsigned int& minimum, unsigned int& maximum) -{ +void ColumnIMask::measure(Task& task, unsigned int& minimum, unsigned int& maximum) { minimum = maximum = 0; - if (task.has (_name)) - minimum = maximum = task.get (_name).length (); + if (task.has(_name)) minimum = maximum = task.get(_name).length(); } //////////////////////////////////////////////////////////////////////////////// -void ColumnIMask::render ( - std::vector & lines, - Task& task, - int width, - Color& color) -{ - if (task.has (_name)) - renderStringRight (lines, width, color, task.get (_name)); +void ColumnIMask::render(std::vector& lines, Task& task, int width, Color& color) { + if (task.has(_name)) renderStringRight(lines, width, color, task.get(_name)); } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/columns/ColIMask.h b/src/columns/ColIMask.h index ccf5ec56b..7fdc4b07f 100644 --- a/src/columns/ColIMask.h +++ b/src/columns/ColIMask.h @@ -29,14 +29,13 @@ #include -class ColumnIMask : public ColumnTypeNumeric -{ -public: - ColumnIMask (); - void measure (Task&, unsigned int&, unsigned int&); - void render (std::vector &, Task&, int, Color&); +class ColumnIMask : public ColumnTypeNumeric { + public: + ColumnIMask(); + void measure(Task&, unsigned int&, unsigned int&); + void render(std::vector&, Task&, int, Color&); -private: + private: }; #endif diff --git a/src/columns/ColLast.cpp b/src/columns/ColLast.cpp index abeaff93d..341f4dcee 100644 --- a/src/columns/ColLast.cpp +++ b/src/columns/ColLast.cpp @@ -31,34 +31,25 @@ #include //////////////////////////////////////////////////////////////////////////////// -ColumnLast::ColumnLast () -{ - _name = "last"; - _style = "number"; - _label = "Last instance"; +ColumnLast::ColumnLast() { + _name = "last"; + _style = "number"; + _label = "Last instance"; _modifiable = false; - _styles = {"number"}; - _examples = {"12"}; + _styles = {"number"}; + _examples = {"12"}; } //////////////////////////////////////////////////////////////////////////////// // Set the minimum and maximum widths for the value. -void ColumnLast::measure (Task& task, unsigned int& minimum, unsigned int& maximum) -{ +void ColumnLast::measure(Task& task, unsigned int& minimum, unsigned int& maximum) { minimum = maximum = 0; - if (task.has (_name)) - minimum = maximum = task.get (_name).length (); + if (task.has(_name)) minimum = maximum = task.get(_name).length(); } //////////////////////////////////////////////////////////////////////////////// -void ColumnLast::render ( - std::vector & lines, - Task& task, - int width, - Color& color) -{ - if (task.has (_name)) - renderStringRight (lines, width, color, task.get (_name)); +void ColumnLast::render(std::vector& lines, Task& task, int width, Color& color) { + if (task.has(_name)) renderStringRight(lines, width, color, task.get(_name)); } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/columns/ColLast.h b/src/columns/ColLast.h index 54d17c782..8f24c291f 100644 --- a/src/columns/ColLast.h +++ b/src/columns/ColLast.h @@ -29,14 +29,13 @@ #include -class ColumnLast : public ColumnTypeNumeric -{ -public: - ColumnLast (); - void measure (Task&, unsigned int&, unsigned int&); - void render (std::vector &, Task&, int, Color&); +class ColumnLast : public ColumnTypeNumeric { + public: + ColumnLast(); + void measure(Task&, unsigned int&, unsigned int&); + void render(std::vector&, Task&, int, Color&); -private: + private: }; #endif diff --git a/src/columns/ColMask.cpp b/src/columns/ColMask.cpp index 3be3418ca..ca5a52f92 100644 --- a/src/columns/ColMask.cpp +++ b/src/columns/ColMask.cpp @@ -31,34 +31,25 @@ #include //////////////////////////////////////////////////////////////////////////////// -ColumnMask::ColumnMask () -{ - _name = "mask"; - _style = "default"; - _label = "Mask"; +ColumnMask::ColumnMask() { + _name = "mask"; + _style = "default"; + _label = "Mask"; _modifiable = false; - _styles = {"default"}; - _examples = {"++++---"}; + _styles = {"default"}; + _examples = {"++++---"}; } //////////////////////////////////////////////////////////////////////////////// // Set the minimum and maximum widths for the value. -void ColumnMask::measure (Task& task, unsigned int& minimum, unsigned int& maximum) -{ +void ColumnMask::measure(Task& task, unsigned int& minimum, unsigned int& maximum) { minimum = maximum = 0; - if (task.has (_name)) - minimum = maximum = task.get (_name).length (); + if (task.has(_name)) minimum = maximum = task.get(_name).length(); } //////////////////////////////////////////////////////////////////////////////// -void ColumnMask::render ( - std::vector & lines, - Task& task, - int width, - Color& color) -{ - if (task.has (_name)) - renderStringLeft (lines, width, color, task.get (_name)); +void ColumnMask::render(std::vector& lines, Task& task, int width, Color& color) { + if (task.has(_name)) renderStringLeft(lines, width, color, task.get(_name)); } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/columns/ColMask.h b/src/columns/ColMask.h index 9346e4dac..b7f28a9f4 100644 --- a/src/columns/ColMask.h +++ b/src/columns/ColMask.h @@ -29,14 +29,13 @@ #include -class ColumnMask : public ColumnTypeString -{ -public: - ColumnMask (); - void measure (Task&, unsigned int&, unsigned int&); - void render (std::vector &, Task&, int, Color&); +class ColumnMask : public ColumnTypeString { + public: + ColumnMask(); + void measure(Task&, unsigned int&, unsigned int&); + void render(std::vector&, Task&, int, Color&); -private: + private: }; #endif diff --git a/src/columns/ColModified.cpp b/src/columns/ColModified.cpp index 658e4b80b..42091e88b 100644 --- a/src/columns/ColModified.cpp +++ b/src/columns/ColModified.cpp @@ -30,9 +30,8 @@ #include //////////////////////////////////////////////////////////////////////////////// -ColumnModified::ColumnModified () -{ - _name = "modified"; +ColumnModified::ColumnModified() { + _name = "modified"; _label = "Modified"; } diff --git a/src/columns/ColModified.h b/src/columns/ColModified.h index 523d2f869..06d79b213 100644 --- a/src/columns/ColModified.h +++ b/src/columns/ColModified.h @@ -29,10 +29,9 @@ #include -class ColumnModified : public ColumnTypeDate -{ -public: - ColumnModified (); +class ColumnModified : public ColumnTypeDate { + public: + ColumnModified(); }; #endif diff --git a/src/columns/ColParent.cpp b/src/columns/ColParent.cpp index dfd63d4d6..e49315904 100644 --- a/src/columns/ColParent.cpp +++ b/src/columns/ColParent.cpp @@ -31,45 +31,37 @@ #include //////////////////////////////////////////////////////////////////////////////// -ColumnParent::ColumnParent () -{ - _name = "parent"; - _style = "long"; - _label = "Parent task"; +ColumnParent::ColumnParent() { + _name = "parent"; + _style = "long"; + _label = "Parent task"; _modifiable = false; - _styles = {"long", "short"}; - _examples = {"f30cb9c3-3fc0-483f-bfb2-3bf134f00694", "f30cb9c3"}; + _styles = {"long", "short"}; + _examples = {"f30cb9c3-3fc0-483f-bfb2-3bf134f00694", "f30cb9c3"}; } //////////////////////////////////////////////////////////////////////////////// // Set the minimum and maximum widths for the value. -void ColumnParent::measure (Task& task, unsigned int& minimum, unsigned int& maximum) -{ +void ColumnParent::measure(Task& task, unsigned int& minimum, unsigned int& maximum) { minimum = maximum = 0; - if (task.has (_name)) - { - if (_style == "default" || _style == "long") minimum = maximum = 36; - else if (_style == "short") minimum = maximum = 8; + if (task.has(_name)) { + if (_style == "default" || _style == "long") + minimum = maximum = 36; + else if (_style == "short") + minimum = maximum = 8; } } //////////////////////////////////////////////////////////////////////////////// -void ColumnParent::render ( - std::vector & lines, - Task& task, - int width, - Color& color) -{ - if (task.has (_name)) - { +void ColumnParent::render(std::vector& lines, Task& task, int width, Color& color) { + if (task.has(_name)) { // f30cb9c3-3fc0-483f-bfb2-3bf134f00694 default // f30cb9c3 short - if (_style == "default" || - _style == "long") - renderStringLeft (lines, width, color, task.get(_name)); + if (_style == "default" || _style == "long") + renderStringLeft(lines, width, color, task.get(_name)); else if (_style == "short") - renderStringLeft (lines, width, color, task.get (_name).substr (0, 8)); + renderStringLeft(lines, width, color, task.get(_name).substr(0, 8)); } } diff --git a/src/columns/ColParent.h b/src/columns/ColParent.h index 2fff8f45d..9332a729d 100644 --- a/src/columns/ColParent.h +++ b/src/columns/ColParent.h @@ -29,14 +29,13 @@ #include -class ColumnParent : public ColumnTypeString -{ -public: - ColumnParent (); - void measure (Task&, unsigned int&, unsigned int&); - void render (std::vector &, Task&, int, Color&); +class ColumnParent : public ColumnTypeString { + public: + ColumnParent(); + void measure(Task&, unsigned int&, unsigned int&); + void render(std::vector&, Task&, int, Color&); -private: + private: }; #endif diff --git a/src/columns/ColProject.cpp b/src/columns/ColProject.cpp index e9444b00c..0454bb5bb 100644 --- a/src/columns/ColProject.cpp +++ b/src/columns/ColProject.cpp @@ -30,120 +30,91 @@ #include #include #include -#include -#include #include -#include +#include +#include #include +#include #include #include //////////////////////////////////////////////////////////////////////////////// -ColumnProject::ColumnProject () -{ - _name = "project"; - _style = "full"; - _label = "Project"; - _styles = {"full", "parent", "indented"}; - _examples = {"home.garden", - "home", - " home.garden"}; - _hyphenate = Context::getContext ().config.getBoolean ("hyphenate"); +ColumnProject::ColumnProject() { + _name = "project"; + _style = "full"; + _label = "Project"; + _styles = {"full", "parent", "indented"}; + _examples = {"home.garden", "home", " home.garden"}; + _hyphenate = Context::getContext().config.getBoolean("hyphenate"); } //////////////////////////////////////////////////////////////////////////////// // Set the minimum and maximum widths for the value. -void ColumnProject::measure (Task& task, unsigned int& minimum, unsigned int& maximum) -{ +void ColumnProject::measure(Task& task, unsigned int& minimum, unsigned int& maximum) { minimum = maximum = 0; - if (task.has (_name)) - { - std::string project = task.get (_name); + if (task.has(_name)) { + std::string project = task.get(_name); - if (_style == "parent") - { - auto period = project.find ('.'); - if (period != std::string::npos) - project = project.substr (0, period); - } - else if (_style == "indented") - { - project = indentProject (project, " ", '.'); + if (_style == "parent") { + auto period = project.find('.'); + if (period != std::string::npos) project = project.substr(0, period); + } else if (_style == "indented") { + project = indentProject(project, " ", '.'); } - minimum = longestWord (project); - maximum = utf8_width (project); + minimum = longestWord(project); + maximum = utf8_width(project); } } //////////////////////////////////////////////////////////////////////////////// -void ColumnProject::render ( - std::vector & lines, - Task& task, - int width, - Color& color) -{ - if (task.has (_name)) - { - std::string project = task.get (_name); - if (_style == "parent") - { - auto period = project.find ('.'); - if (period != std::string::npos) - project = project.substr (0, period); - } - else if (_style == "indented") - { - project = indentProject (project, " ", '.'); +void ColumnProject::render(std::vector& lines, Task& task, int width, Color& color) { + if (task.has(_name)) { + std::string project = task.get(_name); + if (_style == "parent") { + auto period = project.find('.'); + if (period != std::string::npos) project = project.substr(0, period); + } else if (_style == "indented") { + project = indentProject(project, " ", '.'); } - std::vector raw; - wrapText (raw, project, width, _hyphenate); + std::vector raw; + wrapText(raw, project, width, _hyphenate); - for (const auto& i : raw) - renderStringLeft (lines, width, color, i); + for (const auto& i : raw) renderStringLeft(lines, width, color, i); } } //////////////////////////////////////////////////////////////////////////////// -void ColumnProject::modify (Task& task, const std::string& value) -{ +void ColumnProject::modify(Task& task, const std::string& value) { std::string label = " MODIFICATION "; // Only if it's a DOM ref, eval it first. - Lexer lexer (value); + Lexer lexer(value); std::string domRef; Lexer::Type type; - if (lexer.token (domRef, type) && - type == Lexer::Type::dom) - { - try - { + if (lexer.token(domRef, type) && type == Lexer::Type::dom) { + try { Eval e; - e.addSource (domSource); + e.addSource(domSource); Variant v; - e.evaluateInfixExpression (value, v); - task.set (_name, (std::string) v); - Context::getContext ().debug (label + _name + " <-- '" + (std::string) v + "' <-- '" + value + '\''); - } - catch (const std::string& e) - { + e.evaluateInfixExpression(value, v); + task.set(_name, (std::string)v); + Context::getContext().debug(label + _name + " <-- '" + (std::string)v + "' <-- '" + value + + '\''); + } catch (const std::string& e) { // If the expression failed because it didn't look like an expression, // simply store it as-is. - if (e == "The value is not an expression.") - { - task.set (_name, value); - Context::getContext ().debug (label + _name + " <-- '" + value + '\''); - } - else + if (e == "The value is not an expression.") { + task.set(_name, value); + Context::getContext().debug(label + _name + " <-- '" + value + '\''); + } else throw; } - } - else - { - task.set (_name, value); - Context::getContext ().debug (label + _name + " <-- '" + value + '\''); + } else { + task.set(_name, value); + Context::getContext().debug(label + _name + " <-- '" + value + '\''); } } diff --git a/src/columns/ColProject.h b/src/columns/ColProject.h index ab61584c5..ae470f3b9 100644 --- a/src/columns/ColProject.h +++ b/src/columns/ColProject.h @@ -29,15 +29,14 @@ #include -class ColumnProject : public ColumnTypeString -{ -public: - ColumnProject (); - void measure (Task&, unsigned int&, unsigned int&); - void render (std::vector &, Task&, int, Color&); - void modify (Task&, const std::string&); +class ColumnProject : public ColumnTypeString { + public: + ColumnProject(); + void measure(Task&, unsigned int&, unsigned int&); + void render(std::vector&, Task&, int, Color&); + void modify(Task&, const std::string&); -private: + private: bool _hyphenate; }; diff --git a/src/columns/ColRType.cpp b/src/columns/ColRType.cpp index bbe62b2c8..600e2201c 100644 --- a/src/columns/ColRType.cpp +++ b/src/columns/ColRType.cpp @@ -29,72 +29,60 @@ #include #include -#include #include +#include + #include //////////////////////////////////////////////////////////////////////////////// -ColumnRType::ColumnRType () -{ - _name = "rtype"; - _style = "default"; - _label = "Recurrence type"; +ColumnRType::ColumnRType() { + _name = "rtype"; + _style = "default"; + _label = "Recurrence type"; _modifiable = false; - _styles = {"default", "indicator"}; - _examples = {"periodic", "chained"}; + _styles = {"default", "indicator"}; + _examples = {"periodic", "chained"}; } //////////////////////////////////////////////////////////////////////////////// // Overriden so that style <----> label are linked. // Note that you can not determine which gets called first. -void ColumnRType::setStyle (const std::string& value) -{ - Column::setStyle (value); +void ColumnRType::setStyle(const std::string& value) { + Column::setStyle(value); if (_style == "indicator" && _label == "Recurrence type") - _label = _label.substr (0, Context::getContext ().config.get ("rtype.indicator").length ()); + _label = _label.substr(0, Context::getContext().config.get("rtype.indicator").length()); } //////////////////////////////////////////////////////////////////////////////// // Set the minimum and maximum widths for the value. -void ColumnRType::measure (Task& task, unsigned int& minimum, unsigned int& maximum) -{ +void ColumnRType::measure(Task& task, unsigned int& minimum, unsigned int& maximum) { minimum = maximum = 0; - if (task.has (_name)) - { + if (task.has(_name)) { if (_style == "default") - minimum = maximum = task.get (_name).length (); + minimum = maximum = task.get(_name).length(); else if (_style == "indicator") minimum = maximum = 1; } } //////////////////////////////////////////////////////////////////////////////// -void ColumnRType::render ( - std::vector & lines, - Task& task, - int width, - Color& color) -{ - if (task.has (_name)) - { +void ColumnRType::render(std::vector& lines, Task& task, int width, Color& color) { + if (task.has(_name)) { if (_style == "default") - renderStringRight (lines, width, color, task.get (_name)); + renderStringRight(lines, width, color, task.get(_name)); - else if (_style == "indicator") - { - std::string value {" "}; - value[0] = toupper (task.get (_name)[0]); - renderStringRight (lines, width, color, value); + else if (_style == "indicator") { + std::string value{" "}; + value[0] = toupper(task.get(_name)[0]); + renderStringRight(lines, width, color, value); } } } //////////////////////////////////////////////////////////////////////////////// -bool ColumnRType::validate (const std::string& input) const -{ - return input == "periodic" || - input == "chained"; +bool ColumnRType::validate(const std::string& input) const { + return input == "periodic" || input == "chained"; } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/columns/ColRType.h b/src/columns/ColRType.h index d40eae126..dc7b86ffe 100644 --- a/src/columns/ColRType.h +++ b/src/columns/ColRType.h @@ -29,16 +29,15 @@ #include -class ColumnRType : public ColumnTypeString -{ -public: - ColumnRType (); - void setStyle (const std::string&); - void measure (Task&, unsigned int&, unsigned int&); - void render (std::vector &, Task&, int, Color&); - bool validate (const std::string&) const; +class ColumnRType : public ColumnTypeString { + public: + ColumnRType(); + void setStyle(const std::string&); + void measure(Task&, unsigned int&, unsigned int&); + void render(std::vector&, Task&, int, Color&); + bool validate(const std::string&) const; -private: + private: }; #endif diff --git a/src/columns/ColRecur.cpp b/src/columns/ColRecur.cpp index 319705a18..dc6f0fefc 100644 --- a/src/columns/ColRecur.cpp +++ b/src/columns/ColRecur.cpp @@ -31,100 +31,81 @@ #include #include #include -#include -#include #include -#include +#include +#include #include +#include #include //////////////////////////////////////////////////////////////////////////////// -ColumnRecur::ColumnRecur () -{ - _name = "recur"; - _style = "duration"; - _label = "Recur"; +ColumnRecur::ColumnRecur() { + _name = "recur"; + _style = "duration"; + _label = "Recur"; _modifiable = true; - _styles = {"duration", "indicator"}; - _examples = {"weekly", Context::getContext ().config.get ("recurrence.indicator")}; + _styles = {"duration", "indicator"}; + _examples = {"weekly", Context::getContext().config.get("recurrence.indicator")}; } //////////////////////////////////////////////////////////////////////////////// // Overriden so that style <----> label are linked. // Note that you can not determine which gets called first. -void ColumnRecur::setStyle (const std::string& value) -{ - Column::setStyle (value); +void ColumnRecur::setStyle(const std::string& value) { + Column::setStyle(value); if (_style == "indicator" && _label == "Recur") - _label = _label.substr (0, Context::getContext ().config.get ("recurrence.indicator").length ()); + _label = _label.substr(0, Context::getContext().config.get("recurrence.indicator").length()); } //////////////////////////////////////////////////////////////////////////////// // Set the minimum and maximum widths for the value. -void ColumnRecur::measure (Task& task, unsigned int& minimum, unsigned int& maximum) -{ +void ColumnRecur::measure(Task& task, unsigned int& minimum, unsigned int& maximum) { minimum = maximum = 0; - if (task.has (_name)) - { - if (_style == "default" || - _style == "duration") - { - minimum = maximum = Duration (task.get (_name)).formatISO ().length (); - } - else if (_style == "indicator") - { - minimum = maximum = utf8_width (Context::getContext ().config.get ("recurrence.indicator")); + if (task.has(_name)) { + if (_style == "default" || _style == "duration") { + minimum = maximum = Duration(task.get(_name)).formatISO().length(); + } else if (_style == "indicator") { + minimum = maximum = utf8_width(Context::getContext().config.get("recurrence.indicator")); } } } //////////////////////////////////////////////////////////////////////////////// -void ColumnRecur::render ( - std::vector & lines, - Task& task, - int width, - Color& color) -{ - if (task.has (_name)) - { - if (_style == "default" || - _style == "duration") - renderStringRight (lines, width, color, Duration (task.get (_name)).formatISO ()); +void ColumnRecur::render(std::vector& lines, Task& task, int width, Color& color) { + if (task.has(_name)) { + if (_style == "default" || _style == "duration") + renderStringRight(lines, width, color, Duration(task.get(_name)).formatISO()); else if (_style == "indicator") - renderStringRight (lines, width, color, Context::getContext ().config.get ("recurrence.indicator")); + renderStringRight(lines, width, color, + Context::getContext().config.get("recurrence.indicator")); } } //////////////////////////////////////////////////////////////////////////////// // The duration is stored in raw form, but it must still be valid, // and therefore is parsed first. -void ColumnRecur::modify (Task& task, const std::string& value) -{ +void ColumnRecur::modify(Task& task, const std::string& value) { // Try to evaluate 'value'. It might work. Variant evaluatedValue; - try - { + try { Eval e; - e.addSource (domSource); - e.evaluateInfixExpression (value, evaluatedValue); + e.addSource(domSource); + e.evaluateInfixExpression(value, evaluatedValue); } - catch (...) - { - evaluatedValue = Variant (value); + catch (...) { + evaluatedValue = Variant(value); } - if (evaluatedValue.type () == Variant::type_duration) - { + if (evaluatedValue.type() == Variant::type_duration) { // Store the raw value, for 'recur'. std::string label = " MODIFICATION "; - Context::getContext ().debug (label + _name + " <-- '" + value + '\''); - task.set (_name, value); - } - else - throw format ("The duration value '{1}' is not supported.", value); + Context::getContext().debug(label + _name + " <-- '" + value + '\''); + task.set(_name, value); + } else + throw format("The duration value '{1}' is not supported.", value); } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/columns/ColRecur.h b/src/columns/ColRecur.h index e9560dd91..3de674aa9 100644 --- a/src/columns/ColRecur.h +++ b/src/columns/ColRecur.h @@ -31,16 +31,15 @@ // This is 'string', and not 'duration' to force the value to be stored as a // raw duration, so that it can be reevaluated every time. -class ColumnRecur : public ColumnTypeString -{ -public: - ColumnRecur (); - void setStyle (const std::string&); - void measure (Task&, unsigned int&, unsigned int&); - void render (std::vector &, Task&, int, Color&); - void modify (Task&, const std::string&); +class ColumnRecur : public ColumnTypeString { + public: + ColumnRecur(); + void setStyle(const std::string&); + void measure(Task&, unsigned int&, unsigned int&); + void render(std::vector&, Task&, int, Color&); + void modify(Task&, const std::string&); -private: + private: }; #endif diff --git a/src/columns/ColScheduled.cpp b/src/columns/ColScheduled.cpp index e20ae46ba..2a5ca9849 100644 --- a/src/columns/ColScheduled.cpp +++ b/src/columns/ColScheduled.cpp @@ -30,21 +30,18 @@ #include //////////////////////////////////////////////////////////////////////////////// -ColumnScheduled::ColumnScheduled () -{ - _name = "scheduled"; +ColumnScheduled::ColumnScheduled() { + _name = "scheduled"; _label = "Scheduled"; } //////////////////////////////////////////////////////////////////////////////// // Overriden so that style <----> label are linked. // Note that you can not determine which gets called first. -void ColumnScheduled::setStyle (const std::string& value) -{ - Column::setStyle (value); +void ColumnScheduled::setStyle(const std::string& value) { + Column::setStyle(value); - if (_style == "countdown" && _label == "Scheduled") - _label = "Count"; + if (_style == "countdown" && _label == "Scheduled") _label = "Count"; } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/columns/ColScheduled.h b/src/columns/ColScheduled.h index 31beec4ca..c92440212 100644 --- a/src/columns/ColScheduled.h +++ b/src/columns/ColScheduled.h @@ -29,11 +29,10 @@ #include -class ColumnScheduled : public ColumnTypeDate -{ -public: - ColumnScheduled (); - void setStyle (const std::string&); +class ColumnScheduled : public ColumnTypeDate { + public: + ColumnScheduled(); + void setStyle(const std::string&); }; #endif diff --git a/src/columns/ColStart.cpp b/src/columns/ColStart.cpp index d9ee252a4..4a4dcc1a4 100644 --- a/src/columns/ColStart.cpp +++ b/src/columns/ColStart.cpp @@ -32,58 +32,46 @@ #include //////////////////////////////////////////////////////////////////////////////// -ColumnStart::ColumnStart () -{ - _name = "start"; +ColumnStart::ColumnStart() { + _name = "start"; _label = "Started"; - _styles.push_back ("active"); - _examples.push_back (Context::getContext ().config.get ("active.indicator")); + _styles.push_back("active"); + _examples.push_back(Context::getContext().config.get("active.indicator")); } //////////////////////////////////////////////////////////////////////////////// // Overriden so that style <----> label are linked. // Note that you can not determine which gets called first. -void ColumnStart::setStyle (const std::string& value) -{ - Column::setStyle (value); +void ColumnStart::setStyle(const std::string& value) { + Column::setStyle(value); - if (_style == "active" && _label == "Started") - _label = "A"; + if (_style == "active" && _label == "Started") _label = "A"; } //////////////////////////////////////////////////////////////////////////////// // Set the minimum and maximum widths for the value. -void ColumnStart::measure (Task& task, unsigned int& minimum, unsigned int& maximum) -{ +void ColumnStart::measure(Task& task, unsigned int& minimum, unsigned int& maximum) { minimum = maximum = 0; - if (task.has (_name)) - { + if (task.has(_name)) { if (_style == "active") - minimum = maximum = utf8_width (Context::getContext ().config.get ("active.indicator")); + minimum = maximum = utf8_width(Context::getContext().config.get("active.indicator")); else - ColumnTypeDate::measure (task, minimum, maximum); + ColumnTypeDate::measure(task, minimum, maximum); // TODO Throw on bad format. } } //////////////////////////////////////////////////////////////////////////////// -void ColumnStart::render ( - std::vector & lines, - Task& task, - int width, - Color& color) -{ - if (task.has (_name)) - { - if (_style == "active") - { - if (! task.has ("end")) - renderStringRight (lines, width, color, Context::getContext ().config.get ("active.indicator")); - } - else - ColumnTypeDate::render (lines, task, width, color); +void ColumnStart::render(std::vector& lines, Task& task, int width, Color& color) { + if (task.has(_name)) { + if (_style == "active") { + if (!task.has("end")) + renderStringRight(lines, width, color, + Context::getContext().config.get("active.indicator")); + } else + ColumnTypeDate::render(lines, task, width, color); } } diff --git a/src/columns/ColStart.h b/src/columns/ColStart.h index 569b411f7..2196ccabd 100644 --- a/src/columns/ColStart.h +++ b/src/columns/ColStart.h @@ -29,13 +29,12 @@ #include -class ColumnStart : public ColumnTypeDate -{ -public: - ColumnStart (); - void setStyle (const std::string&); - void measure (Task&, unsigned int&, unsigned int&); - void render (std::vector &, Task&, int, Color&); +class ColumnStart : public ColumnTypeDate { + public: + ColumnStart(); + void setStyle(const std::string&); + void measure(Task&, unsigned int&, unsigned int&); + void render(std::vector&, Task&, int, Color&); }; #endif diff --git a/src/columns/ColStatus.cpp b/src/columns/ColStatus.cpp index b2b5e6137..1fed6d73f 100644 --- a/src/columns/ColStatus.cpp +++ b/src/columns/ColStatus.cpp @@ -32,81 +32,75 @@ #include //////////////////////////////////////////////////////////////////////////////// -ColumnStatus::ColumnStatus () -{ - _name = "status"; - _style = "long"; - _label = "Status"; - _styles = {"long", "short"}; - _examples = {"Pending", - "P"}; +ColumnStatus::ColumnStatus() { + _name = "status"; + _style = "long"; + _label = "Status"; + _styles = {"long", "short"}; + _examples = {"Pending", "P"}; } //////////////////////////////////////////////////////////////////////////////// // Overriden so that style <----> label are linked. // Note that you can not determine which gets called first. -void ColumnStatus::setStyle (const std::string& value) -{ - Column::setStyle (value); +void ColumnStatus::setStyle(const std::string& value) { + Column::setStyle(value); - if (_style == "short" && _label == "Status") - _label = "St"; + if (_style == "short" && _label == "Status") _label = "St"; } //////////////////////////////////////////////////////////////////////////////// // Set the minimum and maximum widths for the value. -void ColumnStatus::measure (Task& task, unsigned int& minimum, unsigned int& maximum) -{ - Task::status status = task.getStatus (); +void ColumnStatus::measure(Task& task, unsigned int& minimum, unsigned int& maximum) { + Task::status status = task.getStatus(); - if (_style == "default" || - _style == "long") - { + if (_style == "default" || _style == "long") { if (status == Task::pending) - minimum = maximum = utf8_width ("Pending"); + minimum = maximum = utf8_width("Pending"); else if (status == Task::deleted) - minimum = maximum = utf8_width ("Deleted"); + minimum = maximum = utf8_width("Deleted"); else if (status == Task::waiting) - minimum = maximum = utf8_width ("Waiting"); + minimum = maximum = utf8_width("Waiting"); else if (status == Task::completed) - minimum = maximum = utf8_width ("Completed"); + minimum = maximum = utf8_width("Completed"); else if (status == Task::recurring) - minimum = maximum = utf8_width ("Recurring"); - } - else if (_style == "short") + minimum = maximum = utf8_width("Recurring"); + } else if (_style == "short") minimum = maximum = 1; } //////////////////////////////////////////////////////////////////////////////// -void ColumnStatus::render ( - std::vector & lines, - Task& task, - int width, - Color& color) -{ - Task::status status = task.getStatus (); +void ColumnStatus::render(std::vector& lines, Task& task, int width, Color& color) { + Task::status status = task.getStatus(); std::string value; - if (_style == "default" || - _style == "long") - { - if (status == Task::pending) value = "Pending"; - else if (status == Task::completed) value = "Completed"; - else if (status == Task::deleted) value = "Deleted"; - else if (status == Task::waiting) value = "Waiting"; - else if (status == Task::recurring) value = "Recurring"; + if (_style == "default" || _style == "long") { + if (status == Task::pending) + value = "Pending"; + else if (status == Task::completed) + value = "Completed"; + else if (status == Task::deleted) + value = "Deleted"; + else if (status == Task::waiting) + value = "Waiting"; + else if (status == Task::recurring) + value = "Recurring"; } - else if (_style == "short") - { - if (status == Task::pending) value = "P"; - else if (status == Task::completed) value = "C"; - else if (status == Task::deleted) value = "D"; - else if (status == Task::waiting) value = "W"; - else if (status == Task::recurring) value = "R"; + else if (_style == "short") { + if (status == Task::pending) + value = "P"; + else if (status == Task::completed) + value = "C"; + else if (status == Task::deleted) + value = "D"; + else if (status == Task::waiting) + value = "W"; + else if (status == Task::recurring) + value = "R"; } - renderStringLeft (lines, width, color, value); + renderStringLeft(lines, width, color, value); } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/columns/ColStatus.h b/src/columns/ColStatus.h index 99472466b..9c6f2d9a4 100644 --- a/src/columns/ColStatus.h +++ b/src/columns/ColStatus.h @@ -29,15 +29,14 @@ #include -class ColumnStatus : public ColumnTypeString -{ -public: - ColumnStatus (); - void setStyle (const std::string&); - void measure (Task&, unsigned int&, unsigned int&); - void render (std::vector &, Task&, int, Color&); +class ColumnStatus : public ColumnTypeString { + public: + ColumnStatus(); + void setStyle(const std::string&); + void measure(Task&, unsigned int&, unsigned int&); + void render(std::vector&, Task&, int, Color&); -private: + private: }; #endif diff --git a/src/columns/ColTags.cpp b/src/columns/ColTags.cpp index 8f69d71e8..50ccadf9e 100644 --- a/src/columns/ColTags.cpp +++ b/src/columns/ColTags.cpp @@ -28,154 +28,119 @@ // cmake.h include header must come first #include -#include #include #include -#include #include -#include +#include #include -#include #include +#include +#include + +#include //////////////////////////////////////////////////////////////////////////////// -ColumnTags::ColumnTags () -{ - _name = "tags"; - _style = "list"; - _label = "Tags"; - _styles = {"list", "indicator", "count"}; - _examples = {"home @chore next", - Context::getContext ().config.get ("tag.indicator"), - "[2]"}; +ColumnTags::ColumnTags() { + _name = "tags"; + _style = "list"; + _label = "Tags"; + _styles = {"list", "indicator", "count"}; + _examples = {"home @chore next", Context::getContext().config.get("tag.indicator"), "[2]"}; _hyphenate = false; } //////////////////////////////////////////////////////////////////////////////// // Overriden so that style <----> label are linked. // Note that you can not determine which gets called first. -void ColumnTags::setStyle (const std::string& value) -{ - Column::setStyle (value); +void ColumnTags::setStyle(const std::string& value) { + Column::setStyle(value); - if (_style == "indicator" && - _label == "Tags") - _label = _label.substr (0, Context::getContext ().config.get ("tag.indicator").length ()); + if (_style == "indicator" && _label == "Tags") + _label = _label.substr(0, Context::getContext().config.get("tag.indicator").length()); - else if (_style == "count" && - _label == "Tags") + else if (_style == "count" && _label == "Tags") _label = "Tag"; } //////////////////////////////////////////////////////////////////////////////// // Set the minimum and maximum widths for the value. -void ColumnTags::measure (Task& task, unsigned int& minimum, unsigned int& maximum) -{ +void ColumnTags::measure(Task& task, unsigned int& minimum, unsigned int& maximum) { minimum = maximum = 0; - if (task.has (_name)) - { - if (_style == "indicator") - { - minimum = maximum = utf8_width (Context::getContext ().config.get ("tag.indicator")); - } - else if (_style == "count") - { + if (task.has(_name)) { + if (_style == "indicator") { + minimum = maximum = utf8_width(Context::getContext().config.get("tag.indicator")); + } else if (_style == "count") { minimum = maximum = 3; - } - else if (_style == "default" || - _style == "list") - { - std::string tags = task.get (_name); + } else if (_style == "default" || _style == "list") { + std::string tags = task.get(_name); // Find the widest tag. - if (tags.find (',') != std::string::npos) - { - auto all = split (tags, ','); - for (const auto& tag : all) - { - auto length = utf8_width (tag); - if (length > minimum) - minimum = length; + if (tags.find(',') != std::string::npos) { + auto all = split(tags, ','); + for (const auto& tag : all) { + auto length = utf8_width(tag); + if (length > minimum) minimum = length; } - maximum = utf8_width (tags); + maximum = utf8_width(tags); } // No need to split a single tag. else - minimum = maximum = utf8_width (tags); + minimum = maximum = utf8_width(tags); } } } //////////////////////////////////////////////////////////////////////////////// -void ColumnTags::render ( - std::vector & lines, - Task& task, - int width, - Color& color) -{ - auto all = task.getTags (); - if (all.size() > 0) - { - if (_style == "default" || - _style == "list") - { - if (all.size () > 1) - { - std::sort (all.begin (), all.end ()); - auto tags = join (" ", all); +void ColumnTags::render(std::vector& lines, Task& task, int width, Color& color) { + auto all = task.getTags(); + if (all.size() > 0) { + if (_style == "default" || _style == "list") { + if (all.size() > 1) { + std::sort(all.begin(), all.end()); + auto tags = join(" ", all); - all.clear (); - wrapText (all, tags, width, _hyphenate); + all.clear(); + wrapText(all, tags, width, _hyphenate); - for (const auto& i : all) - renderStringLeft (lines, width, color, i); - } - else - renderStringLeft (lines, width, color, all[0]); - } - else if (_style == "indicator") - { - renderStringRight (lines, width, color, Context::getContext ().config.get ("tag.indicator")); - } - else if (_style == "count") - { - renderStringRight (lines, width, color, '[' + format (static_cast (all.size ())) + ']'); + for (const auto& i : all) renderStringLeft(lines, width, color, i); + } else + renderStringLeft(lines, width, color, all[0]); + } else if (_style == "indicator") { + renderStringRight(lines, width, color, Context::getContext().config.get("tag.indicator")); + } else if (_style == "count") { + renderStringRight(lines, width, color, '[' + format(static_cast(all.size())) + ']'); } } } //////////////////////////////////////////////////////////////////////////////// -void ColumnTags::modify (Task& task, const std::string& value) -{ +void ColumnTags::modify(Task& task, const std::string& value) { std::string label = " MODIFICATION "; std::string commasep; - std::vector tags; + std::vector tags; // If it's a DOM ref, eval it first. - Lexer lexer (value); + Lexer lexer(value); std::string domRef; Lexer::Type type; - if (lexer.token (domRef, type) && - type == Lexer::Type::dom) - { + if (lexer.token(domRef, type) && type == Lexer::Type::dom) { Eval e; - e.addSource (domSource); + e.addSource(domSource); Variant v; - e.evaluateInfixExpression (value, v); - commasep = (std::string) v; + e.evaluateInfixExpression(value, v); + commasep = (std::string)v; } else { - commasep = (std::string) value; + commasep = (std::string)value; } - for (auto& tag : split (commasep, ',')) - { - tags.push_back ((std::string) tag); - Context::getContext ().debug (label + "tags <-- '" + tag + '\''); + for (auto& tag : split(commasep, ',')) { + tags.push_back((std::string)tag); + Context::getContext().debug(label + "tags <-- '" + tag + '\''); - feedback_special_tags (task, tag); + feedback_special_tags(task, tag); } task.setTags(tags); diff --git a/src/columns/ColTags.h b/src/columns/ColTags.h index 481b01bd7..86d58e335 100644 --- a/src/columns/ColTags.h +++ b/src/columns/ColTags.h @@ -29,16 +29,15 @@ #include -class ColumnTags : public ColumnTypeString -{ -public: - ColumnTags (); - void setStyle (const std::string&); - void measure (Task&, unsigned int&, unsigned int&); - void render (std::vector &, Task&, int, Color&); - void modify (Task&, const std::string&); +class ColumnTags : public ColumnTypeString { + public: + ColumnTags(); + void setStyle(const std::string&); + void measure(Task&, unsigned int&, unsigned int&); + void render(std::vector&, Task&, int, Color&); + void modify(Task&, const std::string&); -private: + private: bool _hyphenate; }; diff --git a/src/columns/ColTemplate.cpp b/src/columns/ColTemplate.cpp index 584d08d42..02f536b1c 100644 --- a/src/columns/ColTemplate.cpp +++ b/src/columns/ColTemplate.cpp @@ -31,45 +31,37 @@ #include //////////////////////////////////////////////////////////////////////////////// -ColumnTemplate::ColumnTemplate () -{ - _name = "template"; - _style = "long"; - _label = "Template task"; +ColumnTemplate::ColumnTemplate() { + _name = "template"; + _style = "long"; + _label = "Template task"; _modifiable = false; - _styles = {"long", "short"}; - _examples = {"f30cb9c3-3fc0-483f-bfb2-3bf134f00694", "f30cb9c3"}; + _styles = {"long", "short"}; + _examples = {"f30cb9c3-3fc0-483f-bfb2-3bf134f00694", "f30cb9c3"}; } //////////////////////////////////////////////////////////////////////////////// // Set the minimum and maximum widths for the value. -void ColumnTemplate::measure (Task& task, unsigned int& minimum, unsigned int& maximum) -{ +void ColumnTemplate::measure(Task& task, unsigned int& minimum, unsigned int& maximum) { minimum = maximum = 0; - if (task.has (_name)) - { - if (_style == "default" || _style == "long") minimum = maximum = 36; - else if (_style == "short") minimum = maximum = 8; + if (task.has(_name)) { + if (_style == "default" || _style == "long") + minimum = maximum = 36; + else if (_style == "short") + minimum = maximum = 8; } } //////////////////////////////////////////////////////////////////////////////// -void ColumnTemplate::render ( - std::vector & lines, - Task& task, - int width, - Color& color) -{ - if (task.has (_name)) - { +void ColumnTemplate::render(std::vector& lines, Task& task, int width, Color& color) { + if (task.has(_name)) { // f30cb9c3-3fc0-483f-bfb2-3bf134f00694 default // f30cb9c3 short - if (_style == "default" || - _style == "long") - renderStringLeft (lines, width, color, task.get(_name)); + if (_style == "default" || _style == "long") + renderStringLeft(lines, width, color, task.get(_name)); else if (_style == "short") - renderStringLeft (lines, width, color, task.get (_name).substr (0, 8)); + renderStringLeft(lines, width, color, task.get(_name).substr(0, 8)); } } diff --git a/src/columns/ColTemplate.h b/src/columns/ColTemplate.h index 88c4f88b6..991f42a37 100644 --- a/src/columns/ColTemplate.h +++ b/src/columns/ColTemplate.h @@ -29,14 +29,13 @@ #include -class ColumnTemplate : public ColumnTypeString -{ -public: - ColumnTemplate (); - void measure (Task&, unsigned int&, unsigned int&); - void render (std::vector &, Task&, int, Color&); +class ColumnTemplate : public ColumnTypeString { + public: + ColumnTemplate(); + void measure(Task&, unsigned int&, unsigned int&); + void render(std::vector&, Task&, int, Color&); -private: + private: }; #endif diff --git a/src/columns/ColTypeDate.cpp b/src/columns/ColTypeDate.cpp index 7a882acb6..21597d34f 100644 --- a/src/columns/ColTypeDate.cpp +++ b/src/columns/ColTypeDate.cpp @@ -32,215 +32,165 @@ #include #include #include -#include #include +#include #include //////////////////////////////////////////////////////////////////////////////// -ColumnTypeDate::ColumnTypeDate () -{ - _name = ""; - _type = "date"; - _style = "formatted"; - _label = ""; - _styles = {"formatted", - "julian", - "epoch", - "iso", - "age", - "relative", - "remaining", - "countdown"}; +ColumnTypeDate::ColumnTypeDate() { + _name = ""; + _type = "date"; + _style = "formatted"; + _label = ""; + _styles = {"formatted", "julian", "epoch", "iso", "age", "relative", "remaining", "countdown"}; Datetime now; - now -= 125; // So that "age" is non-zero. - _examples = {now.toString (Context::getContext ().config.get ("dateformat")), - format (now.toJulian (), 13, 12), - now.toEpochString (), - now.toISO (), - Duration (Datetime () - now).formatVague (true), - '-' + Duration (Datetime () - now).formatVague (true), + now -= 125; // So that "age" is non-zero. + _examples = {now.toString(Context::getContext().config.get("dateformat")), + format(now.toJulian(), 13, 12), + now.toEpochString(), + now.toISO(), + Duration(Datetime() - now).formatVague(true), + '-' + Duration(Datetime() - now).formatVague(true), "", - Duration (Datetime () - now).format ()}; + Duration(Datetime() - now).format()}; } //////////////////////////////////////////////////////////////////////////////// // Set the minimum and maximum widths for the value. -void ColumnTypeDate::measure (Task& task, unsigned int& minimum, unsigned int& maximum) -{ +void ColumnTypeDate::measure(Task& task, unsigned int& minimum, unsigned int& maximum) { minimum = maximum = 0; - if (task.has (_name)) - { - Datetime date (task.get_date (_name)); + if (task.has(_name)) { + Datetime date(task.get_date(_name)); - if (_style == "default" || - _style == "formatted") - { + if (_style == "default" || _style == "formatted") { // Determine the output date format, which uses a hierarchy of definitions. // rc.report..dateformat // rc.dateformat.report // rc.dateformat. - std::string format = Context::getContext ().config.get ("report." + _report + ".dateformat"); - if (format == "") - format = Context::getContext ().config.get ("dateformat.report"); - if (format == "") - format = Context::getContext ().config.get ("dateformat"); + std::string format = Context::getContext().config.get("report." + _report + ".dateformat"); + if (format == "") format = Context::getContext().config.get("dateformat.report"); + if (format == "") format = Context::getContext().config.get("dateformat"); - minimum = maximum = Datetime::length (format); - } - else if (_style == "countdown") - { + minimum = maximum = Datetime::length(format); + } else if (_style == "countdown") { Datetime now; - minimum = maximum = Duration (date - now).formatVague (true).length (); - } - else if (_style == "julian") - { - minimum = maximum = format (date.toJulian (), 13, 12).length (); - } - else if (_style == "epoch") - { - minimum = maximum = date.toEpochString ().length (); - } - else if (_style == "iso") - { - minimum = maximum = date.toISO ().length (); - } - else if (_style == "age") - { + minimum = maximum = Duration(date - now).formatVague(true).length(); + } else if (_style == "julian") { + minimum = maximum = format(date.toJulian(), 13, 12).length(); + } else if (_style == "epoch") { + minimum = maximum = date.toEpochString().length(); + } else if (_style == "iso") { + minimum = maximum = date.toISO().length(); + } else if (_style == "age") { Datetime now; if (now > date) - minimum = maximum = Duration (now - date).formatVague (true).length (); + minimum = maximum = Duration(now - date).formatVague(true).length(); else - minimum = maximum = Duration (date - now).formatVague (true).length () + 1; - } - else if (_style == "relative") - { + minimum = maximum = Duration(date - now).formatVague(true).length() + 1; + } else if (_style == "relative") { Datetime now; if (now < date) - minimum = maximum = Duration (date - now).formatVague (true).length (); + minimum = maximum = Duration(date - now).formatVague(true).length(); else - minimum = maximum = Duration (now - date).formatVague (true).length () + 1; - } - else if (_style == "remaining") - { + minimum = maximum = Duration(now - date).formatVague(true).length() + 1; + } else if (_style == "remaining") { Datetime now; - if (date > now) - minimum = maximum = Duration (date - now).formatVague (true).length (); + if (date > now) minimum = maximum = Duration(date - now).formatVague(true).length(); } } } //////////////////////////////////////////////////////////////////////////////// -void ColumnTypeDate::render ( - std::vector & lines, - Task& task, - int width, - Color& color) -{ - if (task.has (_name)) - { - Datetime date (task.get_date (_name)); +void ColumnTypeDate::render(std::vector& lines, Task& task, int width, Color& color) { + if (task.has(_name)) { + Datetime date(task.get_date(_name)); - if (_style == "default" || - _style == "formatted") - { + if (_style == "default" || _style == "formatted") { // Determine the output date format, which uses a hierarchy of definitions. // rc.report..dateformat // rc.dateformat.report // rc.dateformat - std::string format = Context::getContext ().config.get ("report." + _report + ".dateformat"); - if (format == "") - { - format = Context::getContext ().config.get ("dateformat.report"); - if (format == "") - format = Context::getContext ().config.get ("dateformat"); + std::string format = Context::getContext().config.get("report." + _report + ".dateformat"); + if (format == "") { + format = Context::getContext().config.get("dateformat.report"); + if (format == "") format = Context::getContext().config.get("dateformat"); } - renderStringLeft (lines, width, color, date.toString (format)); - } - else if (_style == "countdown") - { + renderStringLeft(lines, width, color, date.toString(format)); + } else if (_style == "countdown") { Datetime now; - renderStringRight (lines, width, color, Duration (date - now).formatVague (true)); - } - else if (_style == "julian") - renderStringRight (lines, width, color, format (date.toJulian (), 13, 12)); + renderStringRight(lines, width, color, Duration(date - now).formatVague(true)); + } else if (_style == "julian") + renderStringRight(lines, width, color, format(date.toJulian(), 13, 12)); else if (_style == "epoch") - renderStringRight (lines, width, color, date.toEpochString ()); + renderStringRight(lines, width, color, date.toEpochString()); else if (_style == "iso") - renderStringLeft (lines, width, color, date.toISO ()); + renderStringLeft(lines, width, color, date.toISO()); - else if (_style == "age") - { + else if (_style == "age") { Datetime now; if (now > date) - renderStringRight (lines, width, color, Duration (now - date).formatVague (true)); + renderStringRight(lines, width, color, Duration(now - date).formatVague(true)); else - renderStringRight (lines, width, color, '-' + Duration (date - now).formatVague (true)); - } - else if (_style == "relative") - { + renderStringRight(lines, width, color, '-' + Duration(date - now).formatVague(true)); + } else if (_style == "relative") { Datetime now; if (now < date) - renderStringRight (lines, width, color, Duration (date - now).formatVague (true)); + renderStringRight(lines, width, color, Duration(date - now).formatVague(true)); else - renderStringRight (lines, width, color, '-' + Duration (now - date).formatVague (true)); + renderStringRight(lines, width, color, '-' + Duration(now - date).formatVague(true)); } - else if (_style == "remaining") - { + else if (_style == "remaining") { Datetime now; if (date > now) - renderStringRight (lines, width, color, Duration (date - now).formatVague (true)); + renderStringRight(lines, width, color, Duration(date - now).formatVague(true)); } } } //////////////////////////////////////////////////////////////////////////////// -bool ColumnTypeDate::validate (const std::string& input) const -{ - return input.length () ? true : false; +bool ColumnTypeDate::validate(const std::string& input) const { + return input.length() ? true : false; } //////////////////////////////////////////////////////////////////////////////// -void ColumnTypeDate::modify (Task& task, const std::string& value) -{ +void ColumnTypeDate::modify(Task& task, const std::string& value) { // Try to evaluate 'value'. It might work. Variant evaluatedValue; - try - { + try { Eval e; - e.addSource (domSource); - e.evaluateInfixExpression (value, evaluatedValue); + e.addSource(domSource); + e.evaluateInfixExpression(value, evaluatedValue); } - catch (...) - { - evaluatedValue = Variant (value); + catch (...) { + evaluatedValue = Variant(value); } // If v is duration, we need to convert it to date (and implicitly add now), // else store as date. std::string label = " MODIFICATION "; - if (evaluatedValue.type () == Variant::type_duration) - { - Context::getContext ().debug (label + _name + " <-- '" + format ("{1}", format (evaluatedValue.get_duration ())) + "' <-- '" + (std::string) evaluatedValue + "' <-- '" + value + '\''); - evaluatedValue.cast (Variant::type_date); - } - else - { - evaluatedValue.cast (Variant::type_date); - Context::getContext ().debug (label + _name + " <-- '" + format ("{1}", evaluatedValue.get_date ()) + "' <-- '" + (std::string) evaluatedValue + "' <-- '" + value + '\''); + if (evaluatedValue.type() == Variant::type_duration) { + Context::getContext().debug(label + _name + " <-- '" + + format("{1}", format(evaluatedValue.get_duration())) + "' <-- '" + + (std::string)evaluatedValue + "' <-- '" + value + '\''); + evaluatedValue.cast(Variant::type_date); + } else { + evaluatedValue.cast(Variant::type_date); + Context::getContext().debug(label + _name + " <-- '" + + format("{1}", evaluatedValue.get_date()) + "' <-- '" + + (std::string)evaluatedValue + "' <-- '" + value + '\''); } // If a date doesn't parse (2/29/2014) then it evaluates to zero. - if (value != "" && - evaluatedValue.get_date () == 0) - throw format ("'{1}' is not a valid date in the '{2}' format.", value, Variant::dateFormat); + if (value != "" && evaluatedValue.get_date() == 0) + throw format("'{1}' is not a valid date in the '{2}' format.", value, Variant::dateFormat); - task.set (_name, evaluatedValue.get_date ()); + task.set(_name, evaluatedValue.get_date()); } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/columns/ColTypeDate.h b/src/columns/ColTypeDate.h index 5d5a9f7b9..dc4bc9aea 100644 --- a/src/columns/ColTypeDate.h +++ b/src/columns/ColTypeDate.h @@ -27,20 +27,20 @@ #ifndef INCLUDED_COLTYPEDATE #define INCLUDED_COLTYPEDATE -#include -#include -#include #include +#include #include -class ColumnTypeDate : public Column -{ -public: - ColumnTypeDate (); - virtual void measure (Task&, unsigned int&, unsigned int&); - virtual void render (std::vector &, Task&, int, Color&); - virtual bool validate (const std::string&) const; - virtual void modify (Task&, const std::string&); +#include +#include + +class ColumnTypeDate : public Column { + public: + ColumnTypeDate(); + virtual void measure(Task&, unsigned int&, unsigned int&); + virtual void render(std::vector&, Task&, int, Color&); + virtual bool validate(const std::string&) const; + virtual void modify(Task&, const std::string&); }; #endif diff --git a/src/columns/ColTypeDuration.cpp b/src/columns/ColTypeDuration.cpp index 8a2182e58..34ae53db1 100644 --- a/src/columns/ColTypeDuration.cpp +++ b/src/columns/ColTypeDuration.cpp @@ -30,50 +30,42 @@ #include #include #include -#include #include +#include #include //////////////////////////////////////////////////////////////////////////////// -ColumnTypeDuration::ColumnTypeDuration () -{ - _type = "duration"; +ColumnTypeDuration::ColumnTypeDuration() { _type = "duration"; } + +//////////////////////////////////////////////////////////////////////////////// +bool ColumnTypeDuration::validate(const std::string& input) const { + return input.length() ? true : false; } //////////////////////////////////////////////////////////////////////////////// -bool ColumnTypeDuration::validate (const std::string& input) const -{ - return input.length () ? true : false; -} - -//////////////////////////////////////////////////////////////////////////////// -void ColumnTypeDuration::modify (Task& task, const std::string& value) -{ +void ColumnTypeDuration::modify(Task& task, const std::string& value) { // Try to evaluate 'value'. It might work. Variant evaluatedValue; - try - { + try { Eval e; - e.addSource (domSource); - e.evaluateInfixExpression (value, evaluatedValue); + e.addSource(domSource); + e.evaluateInfixExpression(value, evaluatedValue); } - catch (...) - { - evaluatedValue = Variant (value); + catch (...) { + evaluatedValue = Variant(value); } // The duration is stored in raw form, but it must still be valid, // and therefore is parsed first. std::string label = " MODIFICATION "; - if (evaluatedValue.type () == Variant::type_duration) - { + if (evaluatedValue.type() == Variant::type_duration) { // Store the raw value, for 'recur'. - Context::getContext ().debug (label + _name + " <-- " + (std::string) evaluatedValue + " <-- '" + value + '\''); - task.set (_name, evaluatedValue); - } - else - throw format ("The duration value '{1}' is not supported.", value); + Context::getContext().debug(label + _name + " <-- " + (std::string)evaluatedValue + " <-- '" + + value + '\''); + task.set(_name, evaluatedValue); + } else + throw format("The duration value '{1}' is not supported.", value); } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/columns/ColTypeDuration.h b/src/columns/ColTypeDuration.h index 6ad3b1753..3d2f9544b 100644 --- a/src/columns/ColTypeDuration.h +++ b/src/columns/ColTypeDuration.h @@ -27,16 +27,16 @@ #ifndef INCLUDED_COLTYPEDURATION #define INCLUDED_COLTYPEDURATION -#include #include #include -class ColumnTypeDuration : public Column -{ -public: - ColumnTypeDuration (); - virtual bool validate (const std::string&) const; - virtual void modify (Task&, const std::string&); +#include + +class ColumnTypeDuration : public Column { + public: + ColumnTypeDuration(); + virtual bool validate(const std::string&) const; + virtual void modify(Task&, const std::string&); }; #endif diff --git a/src/columns/ColTypeNumeric.cpp b/src/columns/ColTypeNumeric.cpp index 5f4dd2d4f..52cc753a7 100644 --- a/src/columns/ColTypeNumeric.cpp +++ b/src/columns/ColTypeNumeric.cpp @@ -30,45 +30,38 @@ #include #include #include -#include #include +#include #include //////////////////////////////////////////////////////////////////////////////// -ColumnTypeNumeric::ColumnTypeNumeric () -{ - _type = "numeric"; +ColumnTypeNumeric::ColumnTypeNumeric() { _type = "numeric"; } + +//////////////////////////////////////////////////////////////////////////////// +bool ColumnTypeNumeric::validate(const std::string& input) const { + return input.length() ? true : false; } //////////////////////////////////////////////////////////////////////////////// -bool ColumnTypeNumeric::validate (const std::string& input) const -{ - return input.length () ? true : false; -} - -//////////////////////////////////////////////////////////////////////////////// -void ColumnTypeNumeric::modify (Task& task, const std::string& value) -{ +void ColumnTypeNumeric::modify(Task& task, const std::string& value) { // Try to evaluate 'value'. It might work. Variant evaluatedValue; - try - { + try { Eval e; - e.addSource (domSource); - e.evaluateInfixExpression (value, evaluatedValue); + e.addSource(domSource); + e.evaluateInfixExpression(value, evaluatedValue); } - catch (...) - { - evaluatedValue = Variant (value); + catch (...) { + evaluatedValue = Variant(value); } std::string label = " MODIFICATION "; - Context::getContext ().debug (label + _name + " <-- '" + evaluatedValue.get_string () + "' <-- '" + value + '\''); + Context::getContext().debug(label + _name + " <-- '" + evaluatedValue.get_string() + "' <-- '" + + value + '\''); // Convert the value of the expression to the correct type if needed - switch (evaluatedValue.type ()) - { + switch (evaluatedValue.type()) { // Expected variants - no conversion case Variant::type_integer: case Variant::type_real: @@ -76,16 +69,16 @@ void ColumnTypeNumeric::modify (Task& task, const std::string& value) // Convertible variants - convert to int case Variant::type_date: case Variant::type_duration: - evaluatedValue.cast (Variant::type_integer); + evaluatedValue.cast(Variant::type_integer); break; // Non-convertible variants case Variant::type_string: - throw format ("The value '{1}' is not a valid numeric value.", evaluatedValue.get_string ()); + throw format("The value '{1}' is not a valid numeric value.", evaluatedValue.get_string()); default: - throw format ("Unexpected variant type: '{1}'", evaluatedValue.type ()); + throw format("Unexpected variant type: '{1}'", evaluatedValue.type()); } - task.set (_name, evaluatedValue); + task.set(_name, evaluatedValue); } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/columns/ColTypeNumeric.h b/src/columns/ColTypeNumeric.h index e530d51f2..edd6508e4 100644 --- a/src/columns/ColTypeNumeric.h +++ b/src/columns/ColTypeNumeric.h @@ -27,16 +27,16 @@ #ifndef INCLUDED_COLTYPENUMERIC #define INCLUDED_COLTYPENUMERIC -#include #include #include -class ColumnTypeNumeric : public Column -{ -public: - ColumnTypeNumeric (); - virtual bool validate (const std::string&) const; - virtual void modify (Task&, const std::string&); +#include + +class ColumnTypeNumeric : public Column { + public: + ColumnTypeNumeric(); + virtual bool validate(const std::string&) const; + virtual void modify(Task&, const std::string&); }; #endif diff --git a/src/columns/ColTypeString.cpp b/src/columns/ColTypeString.cpp index cf71a42dd..538e9057f 100644 --- a/src/columns/ColTypeString.cpp +++ b/src/columns/ColTypeString.cpp @@ -30,64 +30,51 @@ #include #include #include -#include #include +#include #include -#define STRING_INVALID_MOD "The '{1}' attribute does not allow a value of '{2}'." +#define STRING_INVALID_MOD "The '{1}' attribute does not allow a value of '{2}'." //////////////////////////////////////////////////////////////////////////////// -ColumnTypeString::ColumnTypeString () -{ - _type = "string"; +ColumnTypeString::ColumnTypeString() { _type = "string"; } + +//////////////////////////////////////////////////////////////////////////////// +bool ColumnTypeString::validate(const std::string& input) const { + return input.length() ? true : false; } //////////////////////////////////////////////////////////////////////////////// -bool ColumnTypeString::validate (const std::string& input) const -{ - return input.length () ? true : false; -} - -//////////////////////////////////////////////////////////////////////////////// -void ColumnTypeString::modify (Task& task, const std::string& value) -{ +void ColumnTypeString::modify(Task& task, const std::string& value) { std::string label = " MODIFICATION "; // Only if it's a DOM ref, eval it first. - Lexer lexer (value); + Lexer lexer(value); std::string domRef; Lexer::Type type; - if (lexer.token (domRef, type) && - type == Lexer::Type::dom && + if (lexer.token(domRef, type) && type == Lexer::Type::dom && // Ensure 'value' contains only the DOM reference and no other tokens // The lexer.token returns false for end-of-string. // This works as long as all the DOM references we should support consist // only of a single token. - lexer.token (domRef, type) == false) - { + lexer.token(domRef, type) == false) { Eval e; - e.addSource (domSource); + e.addSource(domSource); Variant v; - e.evaluateInfixExpression (value, v); - std::string strValue = (std::string) v; - if (validate (strValue)) - { - task.set (_name, strValue); - Context::getContext ().debug (label + _name + " <-- '" + strValue + "' <-- '" + value + '\''); - } - else - throw format (STRING_INVALID_MOD, _name, value); - } - else - { - if (validate (value)) - { - task.set (_name, value); - Context::getContext ().debug (label + _name + " <-- '" + value + '\''); - } - else - throw format (STRING_INVALID_MOD, _name, value); + e.evaluateInfixExpression(value, v); + std::string strValue = (std::string)v; + if (validate(strValue)) { + task.set(_name, strValue); + Context::getContext().debug(label + _name + " <-- '" + strValue + "' <-- '" + value + '\''); + } else + throw format(STRING_INVALID_MOD, _name, value); + } else { + if (validate(value)) { + task.set(_name, value); + Context::getContext().debug(label + _name + " <-- '" + value + '\''); + } else + throw format(STRING_INVALID_MOD, _name, value); } } diff --git a/src/columns/ColTypeString.h b/src/columns/ColTypeString.h index 4bf5477fa..691a6916e 100644 --- a/src/columns/ColTypeString.h +++ b/src/columns/ColTypeString.h @@ -27,16 +27,16 @@ #ifndef INCLUDED_COLTYPESTRING #define INCLUDED_COLTYPESTRING -#include #include #include -class ColumnTypeString : public Column -{ -public: - ColumnTypeString (); - virtual bool validate (const std::string&) const; - virtual void modify (Task&, const std::string&); +#include + +class ColumnTypeString : public Column { + public: + ColumnTypeString(); + virtual bool validate(const std::string&) const; + virtual void modify(Task&, const std::string&); }; #endif diff --git a/src/columns/ColUDA.cpp b/src/columns/ColUDA.cpp index 95244562c..48686ba70 100644 --- a/src/columns/ColUDA.cpp +++ b/src/columns/ColUDA.cpp @@ -31,34 +31,30 @@ #include #include #include -#include #include -#include +#include #include +#include //////////////////////////////////////////////////////////////////////////////// -ColumnUDAString::ColumnUDAString () -{ - _name = ""; // Gets overwritten at runtime. - _style = "default"; - _label = ""; +ColumnUDAString::ColumnUDAString() { + _name = ""; // Gets overwritten at runtime. + _style = "default"; + _label = ""; _modifiable = true; - _uda = true; - _hyphenate = true; - _styles = {_style, "indicator"}; + _uda = true; + _hyphenate = true; + _styles = {_style, "indicator"}; } //////////////////////////////////////////////////////////////////////////////// -bool ColumnUDAString::validate (const std::string& value) const -{ +bool ColumnUDAString::validate(const std::string& value) const { // No restrictions. - if (_values.size () == 0) - return true; + if (_values.size() == 0) return true; // Look for exact match value. for (auto& i : _values) - if (i == value) - return true; + if (i == value) return true; // Fail if not found. return false; @@ -67,83 +63,61 @@ bool ColumnUDAString::validate (const std::string& value) const //////////////////////////////////////////////////////////////////////////////// // Set the minimum and maximum widths for the value. // -void ColumnUDAString::measure (Task& task, unsigned int& minimum, unsigned int& maximum) -{ +void ColumnUDAString::measure(Task& task, unsigned int& minimum, unsigned int& maximum) { minimum = maximum = 0; - if (task.has (_name)) - { - if (_style == "default") - { - std::string value = task.get (_name); - if (value != "") - { - auto stripped = Color::strip (value); - maximum = longestLine (stripped); - minimum = longestWord (stripped); + if (task.has(_name)) { + if (_style == "default") { + std::string value = task.get(_name); + if (value != "") { + auto stripped = Color::strip(value); + maximum = longestLine(stripped); + minimum = longestWord(stripped); } - } - else if (_style == "indicator") - { - auto indicator = Context::getContext ().config.get ("uda." + _name + ".indicator"); - if (indicator == "") - indicator = "U"; + } else if (_style == "indicator") { + auto indicator = Context::getContext().config.get("uda." + _name + ".indicator"); + if (indicator == "") indicator = "U"; - minimum = maximum = utf8_width (indicator); + minimum = maximum = utf8_width(indicator); } } } //////////////////////////////////////////////////////////////////////////////// -void ColumnUDAString::render ( - std::vector & lines, - Task& task, - int width, - Color& color) -{ - if (task.has (_name)) - { - if (_style == "default") - { - std::string value = task.get (_name); - std::vector raw; - wrapText (raw, value, width, _hyphenate); +void ColumnUDAString::render(std::vector& lines, Task& task, int width, Color& color) { + if (task.has(_name)) { + if (_style == "default") { + std::string value = task.get(_name); + std::vector raw; + wrapText(raw, value, width, _hyphenate); - for (auto& i : raw) - renderStringLeft (lines, width, color, i); - } - else if (_style == "indicator") - { - auto indicator = Context::getContext ().config.get ("uda." + _name + ".indicator"); - if (indicator == "") - indicator = "U"; + for (auto& i : raw) renderStringLeft(lines, width, color, i); + } else if (_style == "indicator") { + auto indicator = Context::getContext().config.get("uda." + _name + ".indicator"); + if (indicator == "") indicator = "U"; - renderStringRight (lines, width, color, indicator); + renderStringRight(lines, width, color, indicator); } } } //////////////////////////////////////////////////////////////////////////////// -ColumnUDANumeric::ColumnUDANumeric () -{ - _name = ""; - _type = "numeric"; - _style = "default"; - _label = ""; - _uda = true; - _styles = {_style, "indicator"}; +ColumnUDANumeric::ColumnUDANumeric() { + _name = ""; + _type = "numeric"; + _style = "default"; + _label = ""; + _uda = true; + _styles = {_style, "indicator"}; } //////////////////////////////////////////////////////////////////////////////// -bool ColumnUDANumeric::validate (const std::string& value) const -{ +bool ColumnUDANumeric::validate(const std::string& value) const { // No restrictions. - if (_values.size () == 0) - return true; + if (_values.size() == 0) return true; // Look for exact match value. for (auto& i : _values) - if (i == value) - return true; + if (i == value) return true; // Fail if not found. return false; @@ -152,75 +126,55 @@ bool ColumnUDANumeric::validate (const std::string& value) const //////////////////////////////////////////////////////////////////////////////// // Set the minimum and maximum widths for the value. // -void ColumnUDANumeric::measure (Task& task, unsigned int& minimum, unsigned int& maximum) -{ +void ColumnUDANumeric::measure(Task& task, unsigned int& minimum, unsigned int& maximum) { minimum = maximum = 0; - if (task.has (_name)) - { - if (_style == "default") - { - auto value = task.get (_name); - if (value != "") - minimum = maximum = value.length (); - } - else if (_style == "indicator") - { - auto indicator = Context::getContext ().config.get ("uda." + _name + ".indicator"); - if (indicator == "") - indicator = "U"; + if (task.has(_name)) { + if (_style == "default") { + auto value = task.get(_name); + if (value != "") minimum = maximum = value.length(); + } else if (_style == "indicator") { + auto indicator = Context::getContext().config.get("uda." + _name + ".indicator"); + if (indicator == "") indicator = "U"; - minimum = maximum = utf8_width (indicator); + minimum = maximum = utf8_width(indicator); } } } //////////////////////////////////////////////////////////////////////////////// -void ColumnUDANumeric::render ( - std::vector & lines, - Task& task, - int width, - Color& color) -{ - if (task.has (_name)) - { - if (_style == "default") - { - auto value = task.get (_name); - renderStringRight (lines, width, color, value); - } - else if (_style == "indicator") - { - auto indicator = Context::getContext ().config.get ("uda." + _name + ".indicator"); - if (indicator == "") - indicator = "U"; +void ColumnUDANumeric::render(std::vector& lines, Task& task, int width, + Color& color) { + if (task.has(_name)) { + if (_style == "default") { + auto value = task.get(_name); + renderStringRight(lines, width, color, value); + } else if (_style == "indicator") { + auto indicator = Context::getContext().config.get("uda." + _name + ".indicator"); + if (indicator == "") indicator = "U"; - renderStringRight (lines, width, color, indicator); + renderStringRight(lines, width, color, indicator); } } } //////////////////////////////////////////////////////////////////////////////// -ColumnUDADate::ColumnUDADate () -{ - _name = ""; - _type = "date"; - _style = "default"; - _label = ""; - _uda = true; - _styles = {_style, "indicator"}; +ColumnUDADate::ColumnUDADate() { + _name = ""; + _type = "date"; + _style = "default"; + _label = ""; + _uda = true; + _styles = {_style, "indicator"}; } //////////////////////////////////////////////////////////////////////////////// -bool ColumnUDADate::validate (const std::string& value) const -{ +bool ColumnUDADate::validate(const std::string& value) const { // No restrictions. - if (_values.size () == 0) - return true; + if (_values.size() == 0) return true; // Look for exact match value. for (auto& i : _values) - if (i == value) - return true; + if (i == value) return true; // Fail if not found. return false; @@ -229,101 +183,77 @@ bool ColumnUDADate::validate (const std::string& value) const //////////////////////////////////////////////////////////////////////////////// // Set the minimum and maximum widths for the value. // -void ColumnUDADate::measure (Task& task, unsigned int& minimum, unsigned int& maximum) -{ +void ColumnUDADate::measure(Task& task, unsigned int& minimum, unsigned int& maximum) { minimum = maximum = 0; - if (task.has (_name)) - { - if (_style == "default") - { - auto value = task.get (_name); - if (value != "") - { + if (task.has(_name)) { + if (_style == "default") { + auto value = task.get(_name); + if (value != "") { // Determine the output date format, which uses a hierarchy of definitions. // rc.report..dateformat // rc.dateformat.report // rc.dateformat - Datetime date (strtoll (value.c_str (), nullptr, 10)); - auto format = Context::getContext ().config.get ("report." + _report + ".dateformat"); - if (format == "") - format = Context::getContext ().config.get ("dateformat.report"); - if (format == "") - format = Context::getContext ().config.get ("dateformat"); + Datetime date(strtoll(value.c_str(), nullptr, 10)); + auto format = Context::getContext().config.get("report." + _report + ".dateformat"); + if (format == "") format = Context::getContext().config.get("dateformat.report"); + if (format == "") format = Context::getContext().config.get("dateformat"); - minimum = maximum = Datetime::length (format); + minimum = maximum = Datetime::length(format); } - } - else if (_style == "indicator") - { - auto indicator = Context::getContext ().config.get ("uda." + _name + ".indicator"); - if (indicator == "") - indicator = "U"; + } else if (_style == "indicator") { + auto indicator = Context::getContext().config.get("uda." + _name + ".indicator"); + if (indicator == "") indicator = "U"; - minimum = maximum = utf8_width (indicator); + minimum = maximum = utf8_width(indicator); } } } //////////////////////////////////////////////////////////////////////////////// -void ColumnUDADate::render ( - std::vector & lines, - Task& task, - int width, - Color& color) -{ - if (task.has (_name)) - { - if (_style == "default") - { - auto value = task.get (_name); +void ColumnUDADate::render(std::vector& lines, Task& task, int width, Color& color) { + if (task.has(_name)) { + if (_style == "default") { + auto value = task.get(_name); // Determine the output date format, which uses a hierarchy of definitions. // rc.report..dateformat // rc.dateformat.report // rc.dateformat. - auto format = Context::getContext ().config.get ("report." + _report + ".dateformat"); - if (format == "") - { - format = Context::getContext ().config.get ("dateformat.report"); - if (format == "") - format = Context::getContext ().config.get ("dateformat"); + auto format = Context::getContext().config.get("report." + _report + ".dateformat"); + if (format == "") { + format = Context::getContext().config.get("dateformat.report"); + if (format == "") format = Context::getContext().config.get("dateformat"); } - renderStringLeft (lines, width, color, Datetime (strtoll (value.c_str (), nullptr, 10)).toString (format)); - } - else if (_style == "indicator") - { - auto indicator = Context::getContext ().config.get ("uda." + _name + ".indicator"); - if (indicator == "") - indicator = "U"; + renderStringLeft(lines, width, color, + Datetime(strtoll(value.c_str(), nullptr, 10)).toString(format)); + } else if (_style == "indicator") { + auto indicator = Context::getContext().config.get("uda." + _name + ".indicator"); + if (indicator == "") indicator = "U"; - renderStringRight (lines, width, color, indicator); + renderStringRight(lines, width, color, indicator); } } } //////////////////////////////////////////////////////////////////////////////// -ColumnUDADuration::ColumnUDADuration () -{ - _name = ""; - _type = "duration"; - _style = "default"; - _label = ""; - _uda = true; - _styles = {_style, "indicator"}; +ColumnUDADuration::ColumnUDADuration() { + _name = ""; + _type = "duration"; + _style = "default"; + _label = ""; + _uda = true; + _styles = {_style, "indicator"}; } //////////////////////////////////////////////////////////////////////////////// -bool ColumnUDADuration::validate (const std::string& value) const -{ +bool ColumnUDADuration::validate(const std::string& value) const { // No restrictions. - if (_values.size () == 0) - return true; + if (_values.size() == 0) return true; // Look for exact match value. for (auto& i : _values) - if (i == value) - return true; + if (i == value) return true; // Fail if not found. return false; @@ -332,54 +262,36 @@ bool ColumnUDADuration::validate (const std::string& value) const //////////////////////////////////////////////////////////////////////////////// // Set the minimum and maximum widths for the value. // -void ColumnUDADuration::measure (Task& task, unsigned int& minimum, unsigned int& maximum) -{ +void ColumnUDADuration::measure(Task& task, unsigned int& minimum, unsigned int& maximum) { minimum = maximum = 0; - if (task.has (_name)) - { - if (_style == "default") - { - auto value = task.get (_name); - if (value != "") - minimum = maximum = Duration (value).formatISO ().length (); - } - else if (_style == "indicator") - { - if (task.has (_name)) - { - auto indicator = Context::getContext ().config.get ("uda." + _name + ".indicator"); - if (indicator == "") - indicator = "U"; + if (task.has(_name)) { + if (_style == "default") { + auto value = task.get(_name); + if (value != "") minimum = maximum = Duration(value).formatISO().length(); + } else if (_style == "indicator") { + if (task.has(_name)) { + auto indicator = Context::getContext().config.get("uda." + _name + ".indicator"); + if (indicator == "") indicator = "U"; - minimum = maximum = utf8_width (indicator); - } - else + minimum = maximum = utf8_width(indicator); + } else minimum = maximum = 0; } } } //////////////////////////////////////////////////////////////////////////////// -void ColumnUDADuration::render ( - std::vector & lines, - Task& task, - int width, - Color& color) -{ - if (task.has (_name)) - { - if (_style == "default") - { - auto value = task.get (_name); - renderStringRight (lines, width, color, Duration (value).formatISO ()); - } - else if (_style == "indicator") - { - auto indicator = Context::getContext ().config.get ("uda." + _name + ".indicator"); - if (indicator == "") - indicator = "U"; +void ColumnUDADuration::render(std::vector& lines, Task& task, int width, + Color& color) { + if (task.has(_name)) { + if (_style == "default") { + auto value = task.get(_name); + renderStringRight(lines, width, color, Duration(value).formatISO()); + } else if (_style == "indicator") { + auto indicator = Context::getContext().config.get("uda." + _name + ".indicator"); + if (indicator == "") indicator = "U"; - renderStringRight (lines, width, color, indicator); + renderStringRight(lines, width, color, indicator); } } } diff --git a/src/columns/ColUDA.h b/src/columns/ColUDA.h index 6e21802a0..ce8aaef97 100644 --- a/src/columns/ColUDA.h +++ b/src/columns/ColUDA.h @@ -27,64 +27,60 @@ #ifndef INCLUDED_COLUDA #define INCLUDED_COLUDA -#include -#include #include #include +#include +#include //////////////////////////////////////////////////////////////////////////////// -class ColumnUDAString : public ColumnTypeString -{ -public: - ColumnUDAString (); - bool validate (const std::string&) const; - void measure (Task&, unsigned int&, unsigned int&); - void render (std::vector &, Task&, int, Color&); +class ColumnUDAString : public ColumnTypeString { + public: + ColumnUDAString(); + bool validate(const std::string&) const; + void measure(Task&, unsigned int&, unsigned int&); + void render(std::vector&, Task&, int, Color&); -public: - std::vector _values; + public: + std::vector _values; -private: + private: bool _hyphenate; }; //////////////////////////////////////////////////////////////////////////////// -class ColumnUDANumeric : public ColumnTypeNumeric -{ -public: - ColumnUDANumeric (); - bool validate (const std::string&) const; - void measure (Task&, unsigned int&, unsigned int&); - void render (std::vector &, Task&, int, Color&); +class ColumnUDANumeric : public ColumnTypeNumeric { + public: + ColumnUDANumeric(); + bool validate(const std::string&) const; + void measure(Task&, unsigned int&, unsigned int&); + void render(std::vector&, Task&, int, Color&); -public: - std::vector _values; + public: + std::vector _values; }; //////////////////////////////////////////////////////////////////////////////// -class ColumnUDADate : public ColumnTypeDate -{ -public: - ColumnUDADate (); - bool validate (const std::string&) const; - void measure (Task&, unsigned int&, unsigned int&); - void render (std::vector &, Task&, int, Color&); +class ColumnUDADate : public ColumnTypeDate { + public: + ColumnUDADate(); + bool validate(const std::string&) const; + void measure(Task&, unsigned int&, unsigned int&); + void render(std::vector&, Task&, int, Color&); -public: - std::vector _values; + public: + std::vector _values; }; //////////////////////////////////////////////////////////////////////////////// -class ColumnUDADuration : public ColumnTypeDuration -{ -public: - ColumnUDADuration (); - bool validate (const std::string&) const; - void measure (Task&, unsigned int&, unsigned int&); - void render (std::vector &, Task&, int, Color&); +class ColumnUDADuration : public ColumnTypeDuration { + public: + ColumnUDADuration(); + bool validate(const std::string&) const; + void measure(Task&, unsigned int&, unsigned int&); + void render(std::vector&, Task&, int, Color&); -public: - std::vector _values; + public: + std::vector _values; }; #endif diff --git a/src/columns/ColUUID.cpp b/src/columns/ColUUID.cpp index ac7822dc0..3b81a4419 100644 --- a/src/columns/ColUUID.cpp +++ b/src/columns/ColUUID.cpp @@ -31,43 +31,37 @@ #include //////////////////////////////////////////////////////////////////////////////// -ColumnUUID::ColumnUUID () -{ - _name = "uuid"; - _style = "long"; - _label = "UUID"; +ColumnUUID::ColumnUUID() { + _name = "uuid"; + _style = "long"; + _label = "UUID"; _modifiable = false; - _styles = {"long", "short"}; - _examples = {"f30cb9c3-3fc0-483f-bfb2-3bf134f00694", "f30cb9c3"}; + _styles = {"long", "short"}; + _examples = {"f30cb9c3-3fc0-483f-bfb2-3bf134f00694", "f30cb9c3"}; } //////////////////////////////////////////////////////////////////////////////// // Set the minimum and maximum widths for the value. -void ColumnUUID::measure (Task&, unsigned int& minimum, unsigned int& maximum) -{ +void ColumnUUID::measure(Task&, unsigned int& minimum, unsigned int& maximum) { // Mandatory attribute, no need to check the value. - if (_style == "default" || _style == "long") minimum = maximum = 36; - else if (_style == "short") minimum = maximum = 8; + if (_style == "default" || _style == "long") + minimum = maximum = 36; + else if (_style == "short") + minimum = maximum = 8; } //////////////////////////////////////////////////////////////////////////////// -void ColumnUUID::render ( - std::vector & lines, - Task& task, - int width, - Color& color) -{ +void ColumnUUID::render(std::vector& lines, Task& task, int width, Color& color) { // No need to check the presence of UUID - all tasks have one. // f30cb9c3-3fc0-483f-bfb2-3bf134f00694 default // f30cb9c3 short - if (_style == "default" || - _style == "long") - renderStringLeft (lines, width, color, task.get (_name)); + if (_style == "default" || _style == "long") + renderStringLeft(lines, width, color, task.get(_name)); else if (_style == "short") - renderStringLeft (lines, width, color, task.get (_name).substr (0, 8)); + renderStringLeft(lines, width, color, task.get(_name).substr(0, 8)); } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/columns/ColUUID.h b/src/columns/ColUUID.h index 5adadcc56..7a8232a41 100644 --- a/src/columns/ColUUID.h +++ b/src/columns/ColUUID.h @@ -29,14 +29,13 @@ #include -class ColumnUUID : public ColumnTypeString -{ -public: - ColumnUUID (); - void measure (Task&, unsigned int&, unsigned int&); - void render (std::vector &, Task&, int, Color&); +class ColumnUUID : public ColumnTypeString { + public: + ColumnUUID(); + void measure(Task&, unsigned int&, unsigned int&); + void render(std::vector&, Task&, int, Color&); -private: + private: }; #endif diff --git a/src/columns/ColUntil.cpp b/src/columns/ColUntil.cpp index fada3aea0..238c2f2df 100644 --- a/src/columns/ColUntil.cpp +++ b/src/columns/ColUntil.cpp @@ -30,9 +30,8 @@ #include //////////////////////////////////////////////////////////////////////////////// -ColumnUntil::ColumnUntil () -{ - _name = "until"; +ColumnUntil::ColumnUntil() { + _name = "until"; _label = "Until"; } diff --git a/src/columns/ColUntil.h b/src/columns/ColUntil.h index 0161fda2e..5f180fba6 100644 --- a/src/columns/ColUntil.h +++ b/src/columns/ColUntil.h @@ -29,10 +29,9 @@ #include -class ColumnUntil : public ColumnTypeDate -{ -public: - ColumnUntil (); +class ColumnUntil : public ColumnTypeDate { + public: + ColumnUntil(); }; #endif diff --git a/src/columns/ColUrgency.cpp b/src/columns/ColUrgency.cpp index cc19b03d3..d202a7d91 100644 --- a/src/columns/ColUrgency.cpp +++ b/src/columns/ColUrgency.cpp @@ -31,39 +31,32 @@ #include //////////////////////////////////////////////////////////////////////////////// -ColumnUrgency::ColumnUrgency () -{ - _name = "urgency"; - _style = "real"; - _label = "Urgency"; +ColumnUrgency::ColumnUrgency() { + _name = "urgency"; + _style = "real"; + _label = "Urgency"; _modifiable = false; - _styles = {"real", "integer"}; - _examples = {"4.6", "4"}; + _styles = {"real", "integer"}; + _examples = {"4.6", "4"}; } //////////////////////////////////////////////////////////////////////////////// // Set the minimum and maximum widths for the value. -void ColumnUrgency::measure (Task& task, unsigned int& minimum, unsigned int& maximum) -{ +void ColumnUrgency::measure(Task& task, unsigned int& minimum, unsigned int& maximum) { if (_style == "default" || _style == "real") - minimum = maximum = format (task.urgency (), 4, 3).length (); + minimum = maximum = format(task.urgency(), 4, 3).length(); else if (_style == "integer") - minimum = maximum = format ((int)task.urgency ()).length (); + minimum = maximum = format((int)task.urgency()).length(); } //////////////////////////////////////////////////////////////////////////////// -void ColumnUrgency::render ( - std::vector & lines, - Task& task, - int width, - Color& color) -{ +void ColumnUrgency::render(std::vector& lines, Task& task, int width, Color& color) { if (_style == "default" || _style == "real") - renderDouble (lines, width, color, task.urgency ()); + renderDouble(lines, width, color, task.urgency()); else if (_style == "integer") - renderInteger (lines, width, color, static_cast (task.urgency ())); + renderInteger(lines, width, color, static_cast(task.urgency())); } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/columns/ColUrgency.h b/src/columns/ColUrgency.h index 918334cd7..c4c31ab0d 100644 --- a/src/columns/ColUrgency.h +++ b/src/columns/ColUrgency.h @@ -29,14 +29,13 @@ #include -class ColumnUrgency : public ColumnTypeNumeric -{ -public: - ColumnUrgency (); - void measure (Task&, unsigned int&, unsigned int&); - void render (std::vector &, Task&, int, Color&); +class ColumnUrgency : public ColumnTypeNumeric { + public: + ColumnUrgency(); + void measure(Task&, unsigned int&, unsigned int&); + void render(std::vector&, Task&, int, Color&); -private: + private: }; #endif diff --git a/src/columns/ColWait.cpp b/src/columns/ColWait.cpp index cd7b1633b..1f2c97e83 100644 --- a/src/columns/ColWait.cpp +++ b/src/columns/ColWait.cpp @@ -30,9 +30,8 @@ #include //////////////////////////////////////////////////////////////////////////////// -ColumnWait::ColumnWait () -{ - _name = "wait"; +ColumnWait::ColumnWait() { + _name = "wait"; _label = "Wait"; } diff --git a/src/columns/ColWait.h b/src/columns/ColWait.h index f5a848b25..7c4b40435 100644 --- a/src/columns/ColWait.h +++ b/src/columns/ColWait.h @@ -29,10 +29,9 @@ #include -class ColumnWait : public ColumnTypeDate -{ -public: - ColumnWait (); +class ColumnWait : public ColumnTypeDate { + public: + ColumnWait(); }; #endif diff --git a/src/columns/Column.cpp b/src/columns/Column.cpp index 5620f6c65..f9231af1a 100644 --- a/src/columns/Column.cpp +++ b/src/columns/Column.cpp @@ -27,10 +27,6 @@ #include // cmake.h include header must come first -#include -#include -#include -#include #include #include #include @@ -43,294 +39,283 @@ #include #include #include -#include #include +#include #include #include #include #include #include +#include +#include #include #include -#include -#include #include -#include +#include +#include #include +#include + +#include +#include //////////////////////////////////////////////////////////////////////////////// // Supports the complete column definition: // // [.] // -Column* Column::factory (const std::string& name, const std::string& report) -{ +Column* Column::factory(const std::string& name, const std::string& report) { // Decompose name into type and style. - auto dot = name.find ('.'); + auto dot = name.find('.'); std::string column_name; std::string column_style; - if (dot != std::string::npos) - { - column_name = name.substr (0, dot); - column_style = name.substr (dot + 1); - } - else - { + if (dot != std::string::npos) { + column_name = name.substr(0, dot); + column_style = name.substr(dot + 1); + } else { column_name = name; column_style = "default"; } Column* c; - if (column_name == "depends") c = new ColumnDepends (); - else if (column_name == "description") c = new ColumnDescription (); - else if (column_name == "due") c = new ColumnDue (); - else if (column_name == "end") c = new ColumnEnd (); - else if (column_name == "entry") c = new ColumnEntry (); - else if (column_name == "id") c = new ColumnID (); - else if (column_name == "imask") c = new ColumnIMask (); - else if (column_name == "last") c = new ColumnLast (); - else if (column_name == "mask") c = new ColumnMask (); - else if (column_name == "modified") c = new ColumnModified (); - else if (column_name == "parent") c = new ColumnParent (); - else if (column_name == "project") c = new ColumnProject (); - else if (column_name == "recur") c = new ColumnRecur (); - else if (column_name == "rtype") c = new ColumnRType (); - else if (column_name == "scheduled") c = new ColumnScheduled (); - else if (column_name == "start") c = new ColumnStart (); - else if (column_name == "status") c = new ColumnStatus (); - else if (column_name == "tags") c = new ColumnTags (); - else if (column_name == "template") c = new ColumnTemplate (); - else if (column_name == "until") c = new ColumnUntil (); - else if (column_name == "urgency") c = new ColumnUrgency (); - else if (column_name == "uuid") c = new ColumnUUID (); - else if (column_name == "wait") c = new ColumnWait (); + if (column_name == "depends") + c = new ColumnDepends(); + else if (column_name == "description") + c = new ColumnDescription(); + else if (column_name == "due") + c = new ColumnDue(); + else if (column_name == "end") + c = new ColumnEnd(); + else if (column_name == "entry") + c = new ColumnEntry(); + else if (column_name == "id") + c = new ColumnID(); + else if (column_name == "imask") + c = new ColumnIMask(); + else if (column_name == "last") + c = new ColumnLast(); + else if (column_name == "mask") + c = new ColumnMask(); + else if (column_name == "modified") + c = new ColumnModified(); + else if (column_name == "parent") + c = new ColumnParent(); + else if (column_name == "project") + c = new ColumnProject(); + else if (column_name == "recur") + c = new ColumnRecur(); + else if (column_name == "rtype") + c = new ColumnRType(); + else if (column_name == "scheduled") + c = new ColumnScheduled(); + else if (column_name == "start") + c = new ColumnStart(); + else if (column_name == "status") + c = new ColumnStatus(); + else if (column_name == "tags") + c = new ColumnTags(); + else if (column_name == "template") + c = new ColumnTemplate(); + else if (column_name == "until") + c = new ColumnUntil(); + else if (column_name == "urgency") + c = new ColumnUrgency(); + else if (column_name == "uuid") + c = new ColumnUUID(); + else if (column_name == "wait") + c = new ColumnWait(); // UDA. - else if (Context::getContext ().config.has ("uda." + column_name + ".type")) - c = Column::uda (column_name); + else if (Context::getContext().config.has("uda." + column_name + ".type")) + c = Column::uda(column_name); else - throw format ("Unrecognized column name '{1}'.", column_name); + throw format("Unrecognized column name '{1}'.", column_name); - c->setReport (report); - c->setStyle (column_style); + c->setReport(report); + c->setStyle(column_style); return c; } //////////////////////////////////////////////////////////////////////////////// // Bulk column instantiation. -void Column::factory (std::map & all) -{ +void Column::factory(std::map& all) { Column* c; - c = new ColumnDepends (); all[c->_name] = c; - c = new ColumnDescription (); all[c->_name] = c; - c = new ColumnDue (); all[c->_name] = c; - c = new ColumnEnd (); all[c->_name] = c; - c = new ColumnEntry (); all[c->_name] = c; - c = new ColumnID (); all[c->_name] = c; - c = new ColumnIMask (); all[c->_name] = c; - c = new ColumnLast (); all[c->_name] = c; - c = new ColumnMask (); all[c->_name] = c; - c = new ColumnModified (); all[c->_name] = c; - c = new ColumnParent (); all[c->_name] = c; - c = new ColumnProject (); all[c->_name] = c; - c = new ColumnRecur (); all[c->_name] = c; - c = new ColumnRType (); all[c->_name] = c; - c = new ColumnScheduled (); all[c->_name] = c; - c = new ColumnStart (); all[c->_name] = c; - c = new ColumnStatus (); all[c->_name] = c; - c = new ColumnTags (); all[c->_name] = c; - c = new ColumnTemplate (); all[c->_name] = c; - c = new ColumnUntil (); all[c->_name] = c; - c = new ColumnUrgency (); all[c->_name] = c; - c = new ColumnUUID (); all[c->_name] = c; - c = new ColumnWait (); all[c->_name] = c; + c = new ColumnDepends(); + all[c->_name] = c; + c = new ColumnDescription(); + all[c->_name] = c; + c = new ColumnDue(); + all[c->_name] = c; + c = new ColumnEnd(); + all[c->_name] = c; + c = new ColumnEntry(); + all[c->_name] = c; + c = new ColumnID(); + all[c->_name] = c; + c = new ColumnIMask(); + all[c->_name] = c; + c = new ColumnLast(); + all[c->_name] = c; + c = new ColumnMask(); + all[c->_name] = c; + c = new ColumnModified(); + all[c->_name] = c; + c = new ColumnParent(); + all[c->_name] = c; + c = new ColumnProject(); + all[c->_name] = c; + c = new ColumnRecur(); + all[c->_name] = c; + c = new ColumnRType(); + all[c->_name] = c; + c = new ColumnScheduled(); + all[c->_name] = c; + c = new ColumnStart(); + all[c->_name] = c; + c = new ColumnStatus(); + all[c->_name] = c; + c = new ColumnTags(); + all[c->_name] = c; + c = new ColumnTemplate(); + all[c->_name] = c; + c = new ColumnUntil(); + all[c->_name] = c; + c = new ColumnUrgency(); + all[c->_name] = c; + c = new ColumnUUID(); + all[c->_name] = c; + c = new ColumnWait(); + all[c->_name] = c; - Column::uda (all); + Column::uda(all); } //////////////////////////////////////////////////////////////////////////////// -void Column::uda (std::map & all) -{ +void Column::uda(std::map& all) { // For each UDA, instantiate and initialize ColumnUDA. - std::set udas; + std::set udas; - for (const auto& i : Context::getContext ().config) - { - if (i.first.substr (0, 4) == "uda.") - { - std::string::size_type period = 4; // One byte after the first '.'. + for (const auto& i : Context::getContext().config) { + if (i.first.substr(0, 4) == "uda.") { + std::string::size_type period = 4; // One byte after the first '.'. - if ((period = i.first.find ('.', period)) != std::string::npos) - udas.insert (i.first.substr (4, period - 4)); + if ((period = i.first.find('.', period)) != std::string::npos) + udas.insert(i.first.substr(4, period - 4)); } } - for (const auto& uda : udas) - { - if (all.find (uda) != all.end ()) - throw format ("The UDA named '{1}' is the same as a core attribute, and is not permitted.", uda); + for (const auto& uda : udas) { + if (all.find(uda) != all.end()) + throw format("The UDA named '{1}' is the same as a core attribute, and is not permitted.", + uda); - Column* c = Column::uda (uda); - if (c) - all[c->_name] = c; + Column* c = Column::uda(uda); + if (c) all[c->_name] = c; } } //////////////////////////////////////////////////////////////////////////////// -Column* Column::uda (const std::string& name) -{ - auto type = Context::getContext ().config.get ("uda." + name + ".type"); - auto label = Context::getContext ().config.get ("uda." + name + ".label"); - auto values = Context::getContext ().config.get ("uda." + name + ".values"); +Column* Column::uda(const std::string& name) { + auto type = Context::getContext().config.get("uda." + name + ".type"); + auto label = Context::getContext().config.get("uda." + name + ".label"); + auto values = Context::getContext().config.get("uda." + name + ".values"); - if (type == "string") - { - auto c = new ColumnUDAString (); + if (type == "string") { + auto c = new ColumnUDAString(); c->_name = name; c->_label = label; - if (values != "") - c->_values = split (values, ','); + if (values != "") c->_values = split(values, ','); return c; - } - else if (type == "numeric") - { - auto c = new ColumnUDANumeric (); + } else if (type == "numeric") { + auto c = new ColumnUDANumeric(); c->_name = name; c->_label = label; - if (values != "") - c->_values = split (values, ','); + if (values != "") c->_values = split(values, ','); return c; - } - else if (type == "date") - { - auto c = new ColumnUDADate (); + } else if (type == "date") { + auto c = new ColumnUDADate(); c->_name = name; c->_label = label; - if (values != "") - c->_values = split (values, ','); + if (values != "") c->_values = split(values, ','); return c; - } - else if (type == "duration") - { - auto c = new ColumnUDADuration (); + } else if (type == "duration") { + auto c = new ColumnUDADuration(); c->_name = name; c->_label = label; - if (values != "") - c->_values = split (values, ','); + if (values != "") c->_values = split(values, ','); return c; - } - else if (type != "") - throw std::string ("User defined attributes may only be of type 'string', 'date', 'duration' or 'numeric'."); + } else if (type != "") + throw std::string( + "User defined attributes may only be of type 'string', 'date', 'duration' or 'numeric'."); return nullptr; } //////////////////////////////////////////////////////////////////////////////// -Column::Column () -: _name ("") -, _type ("string") -, _style ("default") -, _label ("") -, _report ("") -, _modifiable (true) -, _uda (false) -, _fixed_width (false) -{ -} +Column::Column() + : _name(""), + _type("string"), + _style("default"), + _label(""), + _report(""), + _modifiable(true), + _uda(false), + _fixed_width(false) {} //////////////////////////////////////////////////////////////////////////////// -void Column::renderHeader ( - std::vector & lines, - int width, - Color& color) -{ - if (Context::getContext ().verbose ("label") && - _label != "") - { +void Column::renderHeader(std::vector& lines, int width, Color& color) { + if (Context::getContext().verbose("label") && _label != "") { // Create a basic label. std::string header; - header.reserve (width); + header.reserve(width); header = _label; // Create a fungible copy. Color c = color; // Now underline the header, or add a dashed line. - if (Context::getContext ().color () && - Context::getContext ().config.getBoolean ("fontunderline")) - { - c.blend (Color (Color::nocolor, Color::nocolor, true, false, false)); - lines.push_back (c.colorize (leftJustify (header, width))); - } - else - { - lines.push_back (c.colorize (leftJustify (header, width))); - lines.push_back (c.colorize (std::string (width, '-'))); + if (Context::getContext().color() && Context::getContext().config.getBoolean("fontunderline")) { + c.blend(Color(Color::nocolor, Color::nocolor, true, false, false)); + lines.push_back(c.colorize(leftJustify(header, width))); + } else { + lines.push_back(c.colorize(leftJustify(header, width))); + lines.push_back(c.colorize(std::string(width, '-'))); } } } //////////////////////////////////////////////////////////////////////////////// -void Column::setStyle (const std::string& style) -{ - if (style != "default" && - std::find (_styles.begin (), _styles.end (), style) == _styles.end ()) - throw format ("Unrecognized column format '{1}.{2}'", _name, style); +void Column::setStyle(const std::string& style) { + if (style != "default" && std::find(_styles.begin(), _styles.end(), style) == _styles.end()) + throw format("Unrecognized column format '{1}.{2}'", _name, style); _style = style; } //////////////////////////////////////////////////////////////////////////////// // All integer values are right-justified. -void Column::renderInteger ( - std::vector & lines, - int width, - Color& color, - int value) -{ - lines.push_back ( - color.colorize ( - rightJustify (value, width))); +void Column::renderInteger(std::vector& lines, int width, Color& color, int value) { + lines.push_back(color.colorize(rightJustify(value, width))); } //////////////////////////////////////////////////////////////////////////////// // All floating point values are right-justified. -void Column::renderDouble ( - std::vector & lines, - int width, - Color& color, - double value) -{ - lines.push_back ( - color.colorize ( - rightJustify ( - format (value, 4, 3), width))); +void Column::renderDouble(std::vector& lines, int width, Color& color, double value) { + lines.push_back(color.colorize(rightJustify(format(value, 4, 3), width))); } //////////////////////////////////////////////////////////////////////////////// -void Column::renderStringLeft ( - std::vector & lines, - int width, - Color& color, - const std::string& value) -{ - lines.push_back ( - color.colorize ( - leftJustify (value, width))); +void Column::renderStringLeft(std::vector& lines, int width, Color& color, + const std::string& value) { + lines.push_back(color.colorize(leftJustify(value, width))); } //////////////////////////////////////////////////////////////////////////////// -void Column::renderStringRight ( - std::vector & lines, - int width, - Color& color, - const std::string& value) -{ - lines.push_back ( - color.colorize ( - rightJustify (value, width))); +void Column::renderStringRight(std::vector& lines, int width, Color& color, + const std::string& value) { + lines.push_back(color.colorize(rightJustify(value, width))); } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/columns/Column.h b/src/columns/Column.h index 45cf0f613..20dad26fb 100644 --- a/src/columns/Column.h +++ b/src/columns/Column.h @@ -27,51 +27,51 @@ #ifndef INCLUDED_COLUMN #define INCLUDED_COLUMN -#include -#include #include #include -class Column -{ -public: - static Column* factory (const std::string&, const std::string&); - static void factory (std::map &); - static void uda (std::map &); - static Column* uda (const std::string&); +#include +#include - Column (); - virtual ~Column () = default; +class Column { + public: + static Column* factory(const std::string&, const std::string&); + static void factory(std::map&); + static void uda(std::map&); + static Column* uda(const std::string&); - const std::string& name () const { return _name; } - const std::string& style () const { return _style; } - const std::string& label () const { return _label; } - const std::string& type () const { return _type; } - bool modifiable () const { return _modifiable; } - bool is_uda () const { return _uda; } - bool is_fixed_width () const { return _fixed_width; } - std::vector styles () const { return _styles; } - std::vector examples () const { return _examples; } + Column(); + virtual ~Column() = default; - virtual void setStyle (const std::string&); - virtual void setLabel (const std::string& value) { _label = value; } - virtual void setReport (const std::string& value) { _report = value; } + const std::string& name() const { return _name; } + const std::string& style() const { return _style; } + const std::string& label() const { return _label; } + const std::string& type() const { return _type; } + bool modifiable() const { return _modifiable; } + bool is_uda() const { return _uda; } + bool is_fixed_width() const { return _fixed_width; } + std::vector styles() const { return _styles; } + std::vector examples() const { return _examples; } - virtual void measure (const std::string&, unsigned int&, unsigned int&) {}; - virtual void measure (Task&, unsigned int&, unsigned int&) {}; - virtual void renderHeader (std::vector &, int, Color&); - virtual void render (std::vector &, const std::string&, int, Color&) {}; - virtual void render (std::vector &, Task&, int, Color&) {}; - virtual bool validate (const std::string&) const {return false;}; - virtual void modify (Task&, const std::string&) {}; + virtual void setStyle(const std::string&); + virtual void setLabel(const std::string& value) { _label = value; } + virtual void setReport(const std::string& value) { _report = value; } -protected: - void renderInteger (std::vector &, int, Color&, int); - void renderDouble (std::vector &, int, Color&, double); - void renderStringLeft (std::vector &, int, Color&, const std::string&); - void renderStringRight (std::vector &, int, Color&, const std::string&); + virtual void measure(const std::string&, unsigned int&, unsigned int&) {}; + virtual void measure(Task&, unsigned int&, unsigned int&) {}; + virtual void renderHeader(std::vector&, int, Color&); + virtual void render(std::vector&, const std::string&, int, Color&) {}; + virtual void render(std::vector&, Task&, int, Color&) {}; + virtual bool validate(const std::string&) const { return false; }; + virtual void modify(Task&, const std::string&) {}; -protected: + protected: + void renderInteger(std::vector&, int, Color&, int); + void renderDouble(std::vector&, int, Color&, double); + void renderStringLeft(std::vector&, int, Color&, const std::string&); + void renderStringRight(std::vector&, int, Color&, const std::string&); + + protected: std::string _name; std::string _type; std::string _style; @@ -80,8 +80,8 @@ protected: bool _modifiable; bool _uda; bool _fixed_width; - std::vector _styles; - std::vector _examples; + std::vector _styles; + std::vector _examples; }; #endif diff --git a/src/commands/CmdAdd.cpp b/src/commands/CmdAdd.cpp index 749c53499..6661c3d2f 100644 --- a/src/commands/CmdAdd.cpp +++ b/src/commands/CmdAdd.cpp @@ -33,61 +33,55 @@ #include //////////////////////////////////////////////////////////////////////////////// -CmdAdd::CmdAdd () -{ - _keyword = "add"; - _usage = "task add "; - _description = "Adds a new task"; - _read_only = false; - _displays_id = false; - _needs_gc = false; - _uses_context = true; - _accepts_filter = false; +CmdAdd::CmdAdd() { + _keyword = "add"; + _usage = "task add "; + _description = "Adds a new task"; + _read_only = false; + _displays_id = false; + _needs_gc = false; + _uses_context = true; + _accepts_filter = false; _accepts_modifications = true; _accepts_miscellaneous = false; - _category = Command::Category::operation; + _category = Command::Category::operation; } //////////////////////////////////////////////////////////////////////////////// -int CmdAdd::execute (std::string& output) -{ +int CmdAdd::execute(std::string& output) { // Apply the command line modifications to the new task. Task task; // the task is empty, but DOM references can refer to earlier parts of the // command line, e.g., `task add due:20110101 wait:due`. - task.modify (Task::modReplace, true); - Context::getContext ().tdb2.add (task); + task.modify(Task::modReplace, true); + Context::getContext().tdb2.add(task); // Do not display ID 0, users cannot query by that - auto status = task.getStatus (); + auto status = task.getStatus(); // We may have a situation where both new-id and new-uuid config // variables are set. In that case, we'll show the new-uuid, as // it's enduring and never changes, and it's unlikely the caller // asked for this if they just wanted a human-friendly number. - if (Context::getContext ().verbose ("new-uuid") && - status == Task::recurring) - output += format ("Created task {1} (recurrence template).\n", task.get ("uuid")); + if (Context::getContext().verbose("new-uuid") && status == Task::recurring) + output += format("Created task {1} (recurrence template).\n", task.get("uuid")); - else if (Context::getContext ().verbose ("new-uuid") || - (Context::getContext ().verbose ("new-id") && - (status == Task::completed || - status == Task::deleted))) - output += format ("Created task {1}.\n", task.get ("uuid")); + else if (Context::getContext().verbose("new-uuid") || + (Context::getContext().verbose("new-id") && + (status == Task::completed || status == Task::deleted))) + output += format("Created task {1}.\n", task.get("uuid")); - else if (Context::getContext ().verbose ("new-id") && - (status == Task::pending || - status == Task::waiting)) - output += format ("Created task {1}.\n", task.id); + else if (Context::getContext().verbose("new-id") && + (status == Task::pending || status == Task::waiting)) + output += format("Created task {1}.\n", task.id); - else if (Context::getContext ().verbose ("new-id") && - status == Task::recurring) - output += format ("Created task {1} (recurrence template).\n", task.id); + else if (Context::getContext().verbose("new-id") && status == Task::recurring) + output += format("Created task {1} (recurrence template).\n", task.id); - if (Context::getContext ().verbose ("project")) - Context::getContext ().footnote (onProjectChange (task)); + if (Context::getContext().verbose("project")) + Context::getContext().footnote(onProjectChange(task)); return 0; } diff --git a/src/commands/CmdAdd.h b/src/commands/CmdAdd.h index 995938091..e67f7d17e 100644 --- a/src/commands/CmdAdd.h +++ b/src/commands/CmdAdd.h @@ -27,14 +27,14 @@ #ifndef INCLUDED_CMDADD #define INCLUDED_CMDADD -#include #include -class CmdAdd : public Command -{ -public: - CmdAdd (); - int execute (std::string&); +#include + +class CmdAdd : public Command { + public: + CmdAdd(); + int execute(std::string&); }; #endif diff --git a/src/commands/CmdAliases.cpp b/src/commands/CmdAliases.cpp index b6b6074c4..3554a7ee6 100644 --- a/src/commands/CmdAliases.cpp +++ b/src/commands/CmdAliases.cpp @@ -28,31 +28,28 @@ // cmake.h include header must come first #include -#include #include +#include //////////////////////////////////////////////////////////////////////////////// -CmdCompletionAliases::CmdCompletionAliases () -{ - _keyword = "_aliases"; - _usage = "task _aliases"; - _description = "Generates a list of all aliases, for autocompletion purposes"; - _read_only = true; - _displays_id = false; - _needs_gc = false; - _uses_context = false; - _accepts_filter = false; +CmdCompletionAliases::CmdCompletionAliases() { + _keyword = "_aliases"; + _usage = "task _aliases"; + _description = "Generates a list of all aliases, for autocompletion purposes"; + _read_only = true; + _displays_id = false; + _needs_gc = false; + _uses_context = false; + _accepts_filter = false; _accepts_modifications = false; _accepts_miscellaneous = false; - _category = Command::Category::internal; + _category = Command::Category::internal; } //////////////////////////////////////////////////////////////////////////////// -int CmdCompletionAliases::execute (std::string& output) -{ - for (const auto& alias : Context::getContext ().config) - if (alias.first.substr (0, 6) == "alias.") - output += alias.first.substr (6) + '\n'; +int CmdCompletionAliases::execute(std::string& output) { + for (const auto& alias : Context::getContext().config) + if (alias.first.substr(0, 6) == "alias.") output += alias.first.substr(6) + '\n'; return 0; } diff --git a/src/commands/CmdAliases.h b/src/commands/CmdAliases.h index a6fc9bf2a..e8fdd7c9e 100644 --- a/src/commands/CmdAliases.h +++ b/src/commands/CmdAliases.h @@ -27,14 +27,14 @@ #ifndef INCLUDED_CMDALIASES #define INCLUDED_CMDALIASES -#include #include -class CmdCompletionAliases : public Command -{ -public: - CmdCompletionAliases (); - int execute (std::string&); +#include + +class CmdCompletionAliases : public Command { + public: + CmdCompletionAliases(); + int execute(std::string&); }; #endif diff --git a/src/commands/CmdAnnotate.cpp b/src/commands/CmdAnnotate.cpp index 45827aeab..73bbb8882 100644 --- a/src/commands/CmdAnnotate.cpp +++ b/src/commands/CmdAnnotate.cpp @@ -28,111 +28,100 @@ // cmake.h include header must come first #include -#include #include #include +#include #include #include -#include + +#include //////////////////////////////////////////////////////////////////////////////// -CmdAnnotate::CmdAnnotate () -{ - _keyword = "annotate"; - _usage = "task annotate "; - _description = "Adds an annotation to an existing task"; - _read_only = false; - _displays_id = false; - _needs_gc = false; - _uses_context = false; - _accepts_filter = true; +CmdAnnotate::CmdAnnotate() { + _keyword = "annotate"; + _usage = "task annotate "; + _description = "Adds an annotation to an existing task"; + _read_only = false; + _displays_id = false; + _needs_gc = false; + _uses_context = false; + _accepts_filter = true; _accepts_modifications = true; _accepts_miscellaneous = false; - _category = Command::Category::operation; + _category = Command::Category::operation; } //////////////////////////////////////////////////////////////////////////////// -int CmdAnnotate::execute (std::string&) -{ +int CmdAnnotate::execute(std::string&) { int rc = 0; int count = 0; // Apply filter. Filter filter; - std::vector filtered; - filter.subset (filtered); - if (filtered.size () == 0) - { - Context::getContext ().footnote ("No tasks specified."); + std::vector filtered; + filter.subset(filtered); + if (filtered.size() == 0) { + Context::getContext().footnote("No tasks specified."); return 1; } // TODO Complain when no modifications are specified. // Accumulated project change notifications. - std::map projectChanges; + std::map projectChanges; - if(filtered.size() > 1) { + if (filtered.size() > 1) { feedback_affected("This command will alter {1} tasks.", filtered.size()); } - for (auto& task : filtered) - { - Task before (task); + for (auto& task : filtered) { + Task before(task); // Annotate the specified task. - std::string question = format ("Annotate task {1} '{2}'?", - task.identifier (true), - task.get ("description")); + std::string question = + format("Annotate task {1} '{2}'?", task.identifier(true), task.get("description")); - task.modify (Task::modAnnotate, true); + task.modify(Task::modAnnotate, true); - if (permission (before.diff (task) + question, filtered.size ())) - { - Context::getContext ().tdb2.modify (task); + if (permission(before.diff(task) + question, filtered.size())) { + Context::getContext().tdb2.modify(task); ++count; - feedback_affected ("Annotating task {1} '{2}'.", task); - if (Context::getContext ().verbose ("project")) - projectChanges[task.get ("project")] = onProjectChange (task, false); + feedback_affected("Annotating task {1} '{2}'.", task); + if (Context::getContext().verbose("project")) + projectChanges[task.get("project")] = onProjectChange(task, false); // Annotate siblings. - if (task.has ("parent")) - { - if ((Context::getContext ().config.get ("recurrence.confirmation") == "prompt" - && confirm ("This is a recurring task. Do you want to annotate all pending recurrences of this same task?")) || - Context::getContext ().config.getBoolean ("recurrence.confirmation")) - { - auto siblings = Context::getContext ().tdb2.siblings (task); - for (auto& sibling : siblings) - { - sibling.modify (Task::modAnnotate, true); - Context::getContext ().tdb2.modify (sibling); + if (task.has("parent")) { + if ((Context::getContext().config.get("recurrence.confirmation") == "prompt" && + confirm("This is a recurring task. Do you want to annotate all pending recurrences " + "of this same task?")) || + Context::getContext().config.getBoolean("recurrence.confirmation")) { + auto siblings = Context::getContext().tdb2.siblings(task); + for (auto& sibling : siblings) { + sibling.modify(Task::modAnnotate, true); + Context::getContext().tdb2.modify(sibling); ++count; - feedback_affected ("Annotating recurring task {1} '{2}'.", sibling); + feedback_affected("Annotating recurring task {1} '{2}'.", sibling); } // Annotate the parent Task parent; - Context::getContext ().tdb2.get (task.get ("parent"), parent); - parent.modify (Task::modAnnotate, true); - Context::getContext ().tdb2.modify (parent); + Context::getContext().tdb2.get(task.get("parent"), parent); + parent.modify(Task::modAnnotate, true); + Context::getContext().tdb2.modify(parent); } } - } - else - { + } else { std::cout << "Task not annotated.\n"; rc = 1; - if (_permission_quit) - break; + if (_permission_quit) break; } } // Now list the project changes. for (const auto& change : projectChanges) - if (change.first != "") - Context::getContext ().footnote (change.second); + if (change.first != "") Context::getContext().footnote(change.second); - feedback_affected (count == 1 ? "Annotated {1} task." : "Annotated {1} tasks.", count); + feedback_affected(count == 1 ? "Annotated {1} task." : "Annotated {1} tasks.", count); return rc; } diff --git a/src/commands/CmdAnnotate.h b/src/commands/CmdAnnotate.h index db0c47c4e..97f3973df 100644 --- a/src/commands/CmdAnnotate.h +++ b/src/commands/CmdAnnotate.h @@ -27,14 +27,14 @@ #ifndef INCLUDED_CMDANNOTATE #define INCLUDED_CMDANNOTATE -#include #include -class CmdAnnotate : public Command -{ -public: - CmdAnnotate (); - int execute (std::string&); +#include + +class CmdAnnotate : public Command { + public: + CmdAnnotate(); + int execute(std::string&); }; #endif diff --git a/src/commands/CmdAppend.cpp b/src/commands/CmdAppend.cpp index 3cfd820db..d6b68fab2 100644 --- a/src/commands/CmdAppend.cpp +++ b/src/commands/CmdAppend.cpp @@ -28,111 +28,100 @@ // cmake.h include header must come first #include -#include #include #include -#include #include #include +#include + +#include //////////////////////////////////////////////////////////////////////////////// -CmdAppend::CmdAppend () -{ - _keyword = "append"; - _usage = "task append "; - _description = "Appends text to an existing task description"; - _read_only = false; - _displays_id = false; - _needs_gc = false; - _uses_context = false; - _accepts_filter = true; +CmdAppend::CmdAppend() { + _keyword = "append"; + _usage = "task append "; + _description = "Appends text to an existing task description"; + _read_only = false; + _displays_id = false; + _needs_gc = false; + _uses_context = false; + _accepts_filter = true; _accepts_modifications = true; _accepts_miscellaneous = false; - _category = Command::Category::operation; + _category = Command::Category::operation; } //////////////////////////////////////////////////////////////////////////////// -int CmdAppend::execute (std::string&) -{ +int CmdAppend::execute(std::string&) { int rc = 0; int count = 0; // Apply filter. Filter filter; - std::vector filtered; - filter.subset (filtered); - if (filtered.size () == 0) - { - Context::getContext ().footnote ("No tasks specified."); + std::vector filtered; + filter.subset(filtered); + if (filtered.size() == 0) { + Context::getContext().footnote("No tasks specified."); return 1; } // TODO Complain when no modifications are specified. // Accumulated project change notifications. - std::map projectChanges; + std::map projectChanges; - if(filtered.size() > 1) { + if (filtered.size() > 1) { feedback_affected("This command will alter {1} tasks.", filtered.size()); } - for (auto& task : filtered) - { - Task before (task); + for (auto& task : filtered) { + Task before(task); // Append to the specified task. - auto question = format ("Append to task {1} '{2}'?", - task.identifier (true), - task.get ("description")); + auto question = + format("Append to task {1} '{2}'?", task.identifier(true), task.get("description")); - task.modify (Task::modAppend, true); + task.modify(Task::modAppend, true); - if (permission (before.diff (task) + question, filtered.size ())) - { - Context::getContext ().tdb2.modify (task); + if (permission(before.diff(task) + question, filtered.size())) { + Context::getContext().tdb2.modify(task); ++count; - feedback_affected ("Appending to task {1} '{2}'.", task); - if (Context::getContext ().verbose ("project")) - projectChanges[task.get ("project")] = onProjectChange (task, false); + feedback_affected("Appending to task {1} '{2}'.", task); + if (Context::getContext().verbose("project")) + projectChanges[task.get("project")] = onProjectChange(task, false); // Append to siblings. - if (task.has ("parent")) - { - if ((Context::getContext ().config.get ("recurrence.confirmation") == "prompt" - && confirm ("This is a recurring task. Do you want to append to all pending recurrences of this same task?")) || - Context::getContext ().config.getBoolean ("recurrence.confirmation")) - { - std::vector siblings = Context::getContext ().tdb2.siblings (task); - for (auto& sibling : siblings) - { - sibling.modify (Task::modAppend, true); - Context::getContext ().tdb2.modify (sibling); + if (task.has("parent")) { + if ((Context::getContext().config.get("recurrence.confirmation") == "prompt" && + confirm("This is a recurring task. Do you want to append to all pending recurrences " + "of this same task?")) || + Context::getContext().config.getBoolean("recurrence.confirmation")) { + std::vector siblings = Context::getContext().tdb2.siblings(task); + for (auto& sibling : siblings) { + sibling.modify(Task::modAppend, true); + Context::getContext().tdb2.modify(sibling); ++count; - feedback_affected ("Appending to recurring task {1} '{2}'.", sibling); + feedback_affected("Appending to recurring task {1} '{2}'.", sibling); } // Append to the parent Task parent; - Context::getContext ().tdb2.get (task.get ("parent"), parent); - parent.modify (Task::modAppend, true); - Context::getContext ().tdb2.modify (parent); + Context::getContext().tdb2.get(task.get("parent"), parent); + parent.modify(Task::modAppend, true); + Context::getContext().tdb2.modify(parent); } } - } - else - { + } else { std::cout << "Task not appended.\n"; rc = 1; - if (_permission_quit) - break; + if (_permission_quit) break; } } // Now list the project changes. for (const auto& change : projectChanges) - if (change.first != "") - Context::getContext ().footnote (change.second); + if (change.first != "") Context::getContext().footnote(change.second); - feedback_affected (count == 1 ? "Appended {1} task." : "Appended {1} tasks.", count); + feedback_affected(count == 1 ? "Appended {1} task." : "Appended {1} tasks.", count); return rc; } diff --git a/src/commands/CmdAppend.h b/src/commands/CmdAppend.h index a3a6b3a86..41428926f 100644 --- a/src/commands/CmdAppend.h +++ b/src/commands/CmdAppend.h @@ -27,14 +27,14 @@ #ifndef INCLUDED_CMDAPPEND #define INCLUDED_CMDAPPEND -#include #include -class CmdAppend : public Command -{ -public: - CmdAppend (); - int execute (std::string&); +#include + +class CmdAppend : public Command { + public: + CmdAppend(); + int execute(std::string&); }; #endif diff --git a/src/commands/CmdAttributes.cpp b/src/commands/CmdAttributes.cpp index 1ae4d69f0..bc7778572 100644 --- a/src/commands/CmdAttributes.cpp +++ b/src/commands/CmdAttributes.cpp @@ -28,39 +28,37 @@ // cmake.h include header must come first #include -#include -#include -#include #include +#include + +#include +#include //////////////////////////////////////////////////////////////////////////////// -CmdZshAttributes::CmdZshAttributes () -{ - _keyword = "_zshattributes"; - _usage = "task _zshattributes"; - _description = "Generates a list of all attributes, for zsh autocompletion purposes"; - _read_only = true; - _displays_id = false; - _needs_gc = false; - _uses_context = false; - _accepts_filter = false; +CmdZshAttributes::CmdZshAttributes() { + _keyword = "_zshattributes"; + _usage = "task _zshattributes"; + _description = "Generates a list of all attributes, for zsh autocompletion purposes"; + _read_only = true; + _displays_id = false; + _needs_gc = false; + _uses_context = false; + _accepts_filter = false; _accepts_modifications = false; _accepts_miscellaneous = false; - _category = Command::Category::internal; + _category = Command::Category::internal; } //////////////////////////////////////////////////////////////////////////////// -int CmdZshAttributes::execute (std::string& output) -{ +int CmdZshAttributes::execute(std::string& output) { // Get a list of all columns, sort them. - auto columns = Context::getContext ().getColumns (); - std::sort (columns.begin (), columns.end ()); + auto columns = Context::getContext().getColumns(); + std::sort(columns.begin(), columns.end()); std::stringstream out; - for (const auto& col : columns) - out << col << ':' << col << '\n'; + for (const auto& col : columns) out << col << ':' << col << '\n'; - output = out.str (); + output = out.str(); return 0; } diff --git a/src/commands/CmdAttributes.h b/src/commands/CmdAttributes.h index 72c56779a..fa3ef8d81 100644 --- a/src/commands/CmdAttributes.h +++ b/src/commands/CmdAttributes.h @@ -27,14 +27,14 @@ #ifndef INCLUDED_CMDATTRIBUTES #define INCLUDED_CMDATTRIBUTES -#include #include -class CmdZshAttributes : public Command -{ -public: - CmdZshAttributes (); - int execute (std::string&); +#include + +class CmdZshAttributes : public Command { + public: + CmdZshAttributes(); + int execute(std::string&); }; #endif diff --git a/src/commands/CmdBurndown.cpp b/src/commands/CmdBurndown.cpp index 2a3006504..eb2a5e2e9 100644 --- a/src/commands/CmdBurndown.cpp +++ b/src/commands/CmdBurndown.cpp @@ -28,62 +28,57 @@ // cmake.h include header must come first #include -#include -#include -#include -#include -#include -#include #include -#include #include #include -#include -#include +#include #include +#include +#include +#include +#include + +#include +#include +#include +#include // Helper macro. -#define LOC(y,x) (((y) * (_width + 1)) + (x)) +#define LOC(y, x) (((y) * (_width + 1)) + (x)) //////////////////////////////////////////////////////////////////////////////// -class Bar -{ -public: - Bar () = default; - Bar (const Bar&); - Bar& operator= (const Bar&); - ~Bar () = default; +class Bar { + public: + Bar() = default; + Bar(const Bar&); + Bar& operator=(const Bar&); + ~Bar() = default; -public: - int _offset {0}; // from left of chart - std::string _major_label {""}; // x-axis label, major (year/-/month) - std::string _minor_label {""}; // x-axis label, minor (month/week/day) - int _pending {0}; // Number of pending tasks in period - int _started {0}; // Number of started tasks in period - int _done {0}; // Number of done tasks in period - int _added {0}; // Number added in period - int _removed {0}; // Number removed in period + public: + int _offset{0}; // from left of chart + std::string _major_label{""}; // x-axis label, major (year/-/month) + std::string _minor_label{""}; // x-axis label, minor (month/week/day) + int _pending{0}; // Number of pending tasks in period + int _started{0}; // Number of started tasks in period + int _done{0}; // Number of done tasks in period + int _added{0}; // Number added in period + int _removed{0}; // Number removed in period }; //////////////////////////////////////////////////////////////////////////////// -Bar::Bar (const Bar& other) -{ - *this = other; -} +Bar::Bar(const Bar& other) { *this = other; } //////////////////////////////////////////////////////////////////////////////// -Bar& Bar::operator= (const Bar& other) -{ - if (this != &other) - { - _offset = other._offset; +Bar& Bar::operator=(const Bar& other) { + if (this != &other) { + _offset = other._offset; _major_label = other._major_label; _minor_label = other._minor_label; - _pending = other._pending; - _started = other._started; - _done = other._done; - _added = other._added; - _removed = other._removed; + _pending = other._pending; + _started = other._started; + _done = other._done; + _added = other._added; + _removed = other._removed; } return *this; @@ -120,62 +115,60 @@ Bar& Bar::operator= (const Bar& other) // 30 31 01 02 03 04 05 06 07 08 09 10 // Oct Nov // -class Chart -{ -public: - Chart (char); - Chart (const Chart&); // Unimplemented - Chart& operator= (const Chart&); // Unimplemented - ~Chart () = default; +class Chart { + public: + Chart(char); + Chart(const Chart&); // Unimplemented + Chart& operator=(const Chart&); // Unimplemented + ~Chart() = default; - void scan (std::vector &); - void scanForPeak (std::vector &); - std::string render (); + void scan(std::vector&); + void scanForPeak(std::vector&); + std::string render(); -private: - void generateBars (); - void optimizeGrid (); - Datetime quantize (const Datetime&, char); + private: + void generateBars(); + void optimizeGrid(); + Datetime quantize(const Datetime&, char); - Datetime increment (const Datetime&, char); - Datetime decrement (const Datetime&, char); - void maxima (); - void yLabels (std::vector &); - void calculateRates (); - unsigned round_up_to (unsigned, unsigned); - unsigned burndown_size (unsigned); + Datetime increment(const Datetime&, char); + Datetime decrement(const Datetime&, char); + void maxima(); + void yLabels(std::vector&); + void calculateRates(); + unsigned round_up_to(unsigned, unsigned); + unsigned burndown_size(unsigned); -public: - int _width {}; // Terminal width - int _height {}; // Terminal height - int _graph_width {}; // Width of plot area - int _graph_height {}; // Height of plot area - int _max_value {0}; // Largest combined bar value - int _max_label {1}; // Longest y-axis label - std::vector _labels {}; // Y-axis labels - int _estimated_bars {}; // Estimated bar count - int _actual_bars {0}; // Calculated bar count - std::map _bars {}; // Epoch-indexed set of bars - Datetime _earliest {}; // Date of earliest estimated bar - int _carryover_done {0}; // Number of 'done' tasks prior to chart range - char _period {}; // D, W, M - std::string _grid {}; // String representing grid of characters - time_t _peak_epoch {}; // Quantized (D) date of highest pending peak - int _peak_count {0}; // Corresponding peak pending count - int _current_count {0}; // Current pending count - float _net_fix_rate {0.0}; // Calculated fix rate - std::string _completion {}; // Estimated completion date + public: + int _width{}; // Terminal width + int _height{}; // Terminal height + int _graph_width{}; // Width of plot area + int _graph_height{}; // Height of plot area + int _max_value{0}; // Largest combined bar value + int _max_label{1}; // Longest y-axis label + std::vector _labels{}; // Y-axis labels + int _estimated_bars{}; // Estimated bar count + int _actual_bars{0}; // Calculated bar count + std::map _bars{}; // Epoch-indexed set of bars + Datetime _earliest{}; // Date of earliest estimated bar + int _carryover_done{0}; // Number of 'done' tasks prior to chart range + char _period{}; // D, W, M + std::string _grid{}; // String representing grid of characters + time_t _peak_epoch{}; // Quantized (D) date of highest pending peak + int _peak_count{0}; // Corresponding peak pending count + int _current_count{0}; // Current pending count + float _net_fix_rate{0.0}; // Calculated fix rate + std::string _completion{}; // Estimated completion date }; //////////////////////////////////////////////////////////////////////////////// -Chart::Chart (char type) -{ +Chart::Chart(char type) { // How much space is there to render in? This chart will occupy the // maximum space, and the width drives various other parameters. - _width = Context::getContext ().getWidth (); - _height = Context::getContext ().getHeight () - - Context::getContext ().config.getInteger ("reserved.lines") - - 1; // Allow for new line with prompt. + _width = Context::getContext().getWidth(); + _height = Context::getContext().getHeight() - + Context::getContext().config.getInteger("reserved.lines") - + 1; // Allow for new line with prompt. _graph_height = _height - 7; _graph_width = _width - _max_label - 14; @@ -189,39 +182,34 @@ Chart::Chart (char type) //////////////////////////////////////////////////////////////////////////////// // Scan all tasks, quantize the dates by day, and find the peak pending count // and corresponding epoch. -void Chart::scanForPeak (std::vector & tasks) -{ - std::map pending; +void Chart::scanForPeak(std::vector& tasks) { + std::map pending; _current_count = 0; - for (auto& task : tasks) - { + for (auto& task : tasks) { // The entry date is when the counting starts. - Datetime entry (task.get_date ("entry")); + Datetime entry(task.get_date("entry")); Datetime end; - if (task.has ("end")) - end = Datetime (task.get_date ("end")); + if (task.has("end")) + end = Datetime(task.get_date("end")); else ++_current_count; - while (entry < end) - { - time_t epoch = quantize (entry.toEpoch (), 'D').toEpoch (); - if (pending.find (epoch) != pending.end ()) + while (entry < end) { + time_t epoch = quantize(entry.toEpoch(), 'D').toEpoch(); + if (pending.find(epoch) != pending.end()) ++pending[epoch]; else pending[epoch] = 1; - entry = increment (entry, 'D'); + entry = increment(entry, 'D'); } } // Find the peak and peak date. - for (auto& count : pending) - { - if (count.second > _peak_count) - { + for (auto& count : pending) { + if (count.second > _peak_count) { _peak_count = count.second; _peak_epoch = count.first; } @@ -229,120 +217,93 @@ void Chart::scanForPeak (std::vector & tasks) } //////////////////////////////////////////////////////////////////////////////// -void Chart::scan (std::vector & tasks) -{ - generateBars (); +void Chart::scan(std::vector& tasks) { + generateBars(); // Not quantized, so that "while (xxx < now)" is inclusive. Datetime now; time_t epoch; - auto& config = Context::getContext ().config; + auto& config = Context::getContext().config; bool cumulative; - if (config.has ("burndown.cumulative")) - { - cumulative = config.getBoolean ("burndown.cumulative"); - } - else - { + if (config.has("burndown.cumulative")) { + cumulative = config.getBoolean("burndown.cumulative"); + } else { cumulative = true; } - for (auto& task : tasks) - { + for (auto& task : tasks) { // The entry date is when the counting starts. - Datetime from = quantize (Datetime (task.get_date ("entry")), _period); - epoch = from.toEpoch (); + Datetime from = quantize(Datetime(task.get_date("entry")), _period); + epoch = from.toEpoch(); - if (_bars.find (epoch) != _bars.end ()) - ++_bars[epoch]._added; + if (_bars.find(epoch) != _bars.end()) ++_bars[epoch]._added; // e--> e--s--> // ppp> pppsss> - Task::status status = task.getStatus (); - if (status == Task::pending || - status == Task::waiting) - { - if (task.has ("start")) - { - Datetime start = quantize (Datetime (task.get_date ("start")), _period); - while (from < start) - { - epoch = from.toEpoch (); - if (_bars.find (epoch) != _bars.end ()) - ++_bars[epoch]._pending; - from = increment (from, _period); + Task::status status = task.getStatus(); + if (status == Task::pending || status == Task::waiting) { + if (task.has("start")) { + Datetime start = quantize(Datetime(task.get_date("start")), _period); + while (from < start) { + epoch = from.toEpoch(); + if (_bars.find(epoch) != _bars.end()) ++_bars[epoch]._pending; + from = increment(from, _period); } - while (from < now) - { - epoch = from.toEpoch (); - if (_bars.find (epoch) != _bars.end ()) - ++_bars[epoch]._started; - from = increment (from, _period); + while (from < now) { + epoch = from.toEpoch(); + if (_bars.find(epoch) != _bars.end()) ++_bars[epoch]._started; + from = increment(from, _period); } - } - else - { - while (from < now) - { - epoch = from.toEpoch (); - if (_bars.find (epoch) != _bars.end ()) - ++_bars[epoch]._pending; - from = increment (from, _period); + } else { + while (from < now) { + epoch = from.toEpoch(); + if (_bars.find(epoch) != _bars.end()) ++_bars[epoch]._pending; + from = increment(from, _period); } } } // e--C e--s--C // pppd> pppsssd> - else if (status == Task::completed) - { + else if (status == Task::completed) { // Truncate history so it starts at 'earliest' for completed tasks. - Datetime end = quantize (Datetime (task.get_date ("end")), _period); - epoch = end.toEpoch (); + Datetime end = quantize(Datetime(task.get_date("end")), _period); + epoch = end.toEpoch(); - if (_bars.find (epoch) != _bars.end ()) - ++_bars[epoch]._removed; + if (_bars.find(epoch) != _bars.end()) ++_bars[epoch]._removed; - while (from < end) - { - epoch = from.toEpoch (); - if (_bars.find (epoch) != _bars.end ()) - ++_bars[epoch]._pending; - from = increment (from, _period); + while (from < end) { + epoch = from.toEpoch(); + if (_bars.find(epoch) != _bars.end()) ++_bars[epoch]._pending; + from = increment(from, _period); } - if (cumulative) - { - while (from < now) - { - epoch = from.toEpoch (); - if (_bars.find (epoch) != _bars.end ()) - ++_bars[epoch]._done; - from = increment (from, _period); + if (cumulative) { + while (from < now) { + epoch = from.toEpoch(); + if (_bars.find(epoch) != _bars.end()) ++_bars[epoch]._done; + from = increment(from, _period); } // Maintain a running total of 'done' tasks that are off the left of the // chart. - if (end < _earliest) - { + if (end < _earliest) { ++_carryover_done; continue; } } - else - { - epoch = from.toEpoch (); - if (_bars.find (epoch) != _bars.end ()) - ++_bars[epoch]._done; + else { + epoch = from.toEpoch(); + if (_bars.find(epoch) != _bars.end()) ++_bars[epoch]._done; } } } // Size the data. - maxima (); + maxima(); } //////////////////////////////////////////////////////////////////////////////// @@ -364,153 +325,146 @@ void Chart::scan (std::vector & tasks) // | ADD rate 1.7/d Estimated completion 8/12/2010 | // | Don/Delete rate 1.3/d | // +---------------------------------------------------------------------+ -std::string Chart::render () -{ - if (_graph_height < 5 || // a 4-line graph is essentially unreadable. - _graph_width < 2) // A single-bar graph is useless. +std::string Chart::render() { + if (_graph_height < 5 || // a 4-line graph is essentially unreadable. + _graph_width < 2) // A single-bar graph is useless. { - return std::string ("Terminal window too small to draw a graph.\n"); + return std::string("Terminal window too small to draw a graph.\n"); } - else if (_graph_height > 1000 || // each line is a string allloc - _graph_width > 1000) - { - return std::string ("Terminal window too large to draw a graph.\n"); + else if (_graph_height > 1000 || // each line is a string allloc + _graph_width > 1000) { + return std::string("Terminal window too large to draw a graph.\n"); } - if (_max_value == 0) - Context::getContext ().footnote ("No matches."); + if (_max_value == 0) Context::getContext().footnote("No matches."); // Create a grid, folded into a string. _grid = ""; - for (int i = 0; i < _height; ++i) - _grid += std::string (_width, ' ') + '\n'; + for (int i = 0; i < _height; ++i) _grid += std::string(_width, ' ') + '\n'; // Title. - std::string title = _period == 'D' ? "Daily" - : _period == 'W' ? "Weekly" - : "Monthly"; - title += std::string (" Burndown"); - _grid.replace (LOC (0, (_width - title.length ()) / 2), title.length (), title); + std::string title = _period == 'D' ? "Daily" : _period == 'W' ? "Weekly" : "Monthly"; + title += std::string(" Burndown"); + _grid.replace(LOC(0, (_width - title.length()) / 2), title.length(), title); // Legend. - _grid.replace (LOC (_graph_height / 2 - 1, _width - 10), 10, "DD " + leftJustify ("Done", 7)); - _grid.replace (LOC (_graph_height / 2, _width - 10), 10, "SS " + leftJustify ("Started", 7)); - _grid.replace (LOC (_graph_height / 2 + 1, _width - 10), 10, "PP " + leftJustify ("Pending", 7)); + _grid.replace(LOC(_graph_height / 2 - 1, _width - 10), 10, "DD " + leftJustify("Done", 7)); + _grid.replace(LOC(_graph_height / 2, _width - 10), 10, "SS " + leftJustify("Started", 7)); + _grid.replace(LOC(_graph_height / 2 + 1, _width - 10), 10, "PP " + leftJustify("Pending", 7)); // Determine y-axis labelling. - std::vector _labels; - yLabels (_labels); - _max_label = (int) log10 ((double) _labels[2]) + 1; + std::vector _labels; + yLabels(_labels); + _max_label = (int)log10((double)_labels[2]) + 1; // Draw y-axis. - for (int i = 0; i < _graph_height; ++i) - _grid.replace (LOC (i + 1, _max_label + 1), 1, "|"); + for (int i = 0; i < _graph_height; ++i) _grid.replace(LOC(i + 1, _max_label + 1), 1, "|"); // Draw y-axis labels. - char label [12]; - snprintf (label, 12, "%*d", _max_label, _labels[2]); - _grid.replace (LOC (1, _max_label - strlen (label)), strlen (label), label); - snprintf (label, 12, "%*d", _max_label, _labels[1]); - _grid.replace (LOC (1 + (_graph_height / 2), _max_label - strlen (label)), strlen (label), label); - _grid.replace (LOC (_graph_height + 1, _max_label - 1), 1, "0"); + char label[12]; + snprintf(label, 12, "%*d", _max_label, _labels[2]); + _grid.replace(LOC(1, _max_label - strlen(label)), strlen(label), label); + snprintf(label, 12, "%*d", _max_label, _labels[1]); + _grid.replace(LOC(1 + (_graph_height / 2), _max_label - strlen(label)), strlen(label), label); + _grid.replace(LOC(_graph_height + 1, _max_label - 1), 1, "0"); // Draw x-axis. - _grid.replace (LOC (_height - 6, _max_label + 1), 1, "+"); - _grid.replace (LOC (_height - 6, _max_label + 2), _graph_width, std::string (_graph_width, '-')); + _grid.replace(LOC(_height - 6, _max_label + 1), 1, "+"); + _grid.replace(LOC(_height - 6, _max_label + 2), _graph_width, std::string(_graph_width, '-')); // Draw x-axis labels. - std::vector bars_in_sequence; - for (auto& bar : _bars) - bars_in_sequence.push_back (bar.first); + std::vector bars_in_sequence; + for (auto& bar : _bars) bars_in_sequence.push_back(bar.first); - std::sort (bars_in_sequence.begin (), bars_in_sequence.end ()); + std::sort(bars_in_sequence.begin(), bars_in_sequence.end()); std::string _major_label; - for (auto& seq : bars_in_sequence) - { + for (auto& seq : bars_in_sequence) { Bar bar = _bars[seq]; // If it fits within the allowed space. - if (bar._offset < _actual_bars) - { - _grid.replace (LOC (_height - 5, _max_label + 3 + ((_actual_bars - bar._offset - 1) * 3)), bar._minor_label.length (), bar._minor_label); + if (bar._offset < _actual_bars) { + _grid.replace(LOC(_height - 5, _max_label + 3 + ((_actual_bars - bar._offset - 1) * 3)), + bar._minor_label.length(), bar._minor_label); if (_major_label != bar._major_label) - _grid.replace (LOC (_height - 4, _max_label + 2 + ((_actual_bars - bar._offset - 1) * 3)), bar._major_label.length (), ' ' + bar._major_label); + _grid.replace(LOC(_height - 4, _max_label + 2 + ((_actual_bars - bar._offset - 1) * 3)), + bar._major_label.length(), ' ' + bar._major_label); _major_label = bar._major_label; } } // Draw bars. - for (auto& seq : bars_in_sequence) - { + for (auto& seq : bars_in_sequence) { Bar bar = _bars[seq]; // If it fits within the allowed space. - if (bar._offset < _actual_bars) - { - int pending = ( bar._pending * _graph_height) / _labels[2]; - int started = ((bar._pending + bar._started) * _graph_height) / _labels[2]; - int done = ((bar._pending + bar._started + bar._done + _carryover_done) * _graph_height) / _labels[2]; + if (bar._offset < _actual_bars) { + int pending = (bar._pending * _graph_height) / _labels[2]; + int started = ((bar._pending + bar._started) * _graph_height) / _labels[2]; + int done = ((bar._pending + bar._started + bar._done + _carryover_done) * _graph_height) / + _labels[2]; for (int b = 0; b < pending; ++b) - _grid.replace (LOC (_graph_height - b, _max_label + 3 + ((_actual_bars - bar._offset - 1) * 3)), 2, "PP"); + _grid.replace( + LOC(_graph_height - b, _max_label + 3 + ((_actual_bars - bar._offset - 1) * 3)), 2, + "PP"); for (int b = pending; b < started; ++b) - _grid.replace (LOC (_graph_height - b, _max_label + 3 + ((_actual_bars - bar._offset - 1) * 3)), 2, "SS"); + _grid.replace( + LOC(_graph_height - b, _max_label + 3 + ((_actual_bars - bar._offset - 1) * 3)), 2, + "SS"); for (int b = started; b < done; ++b) - _grid.replace (LOC (_graph_height - b, _max_label + 3 + ((_actual_bars - bar._offset - 1) * 3)), 2, "DD"); + _grid.replace( + LOC(_graph_height - b, _max_label + 3 + ((_actual_bars - bar._offset - 1) * 3)), 2, + "DD"); } } // Draw rates. - calculateRates (); + calculateRates(); char rate[12]; if (_net_fix_rate != 0.0) - snprintf (rate, 12, "%.1f/d", _net_fix_rate); + snprintf(rate, 12, "%.1f/d", _net_fix_rate); else - strcpy (rate, "-"); + strcpy(rate, "-"); - _grid.replace (LOC (_height - 2, _max_label + 3), 22 + strlen (rate), std::string ("Net Fix Rate: ") + rate); + _grid.replace(LOC(_height - 2, _max_label + 3), 22 + strlen(rate), + std::string("Net Fix Rate: ") + rate); // Draw completion date. - if (_completion.length ()) - _grid.replace (LOC (_height - 1, _max_label + 3), 22 + _completion.length (), "Estimated completion: " + _completion); + if (_completion.length()) + _grid.replace(LOC(_height - 1, _max_label + 3), 22 + _completion.length(), + "Estimated completion: " + _completion); - optimizeGrid (); + optimizeGrid(); - if (Context::getContext ().color ()) - { + if (Context::getContext().color()) { // Colorize the grid. - Color color_pending (Context::getContext ().config.get ("color.burndown.pending")); - Color color_done (Context::getContext ().config.get ("color.burndown.done")); - Color color_started (Context::getContext ().config.get ("color.burndown.started")); + Color color_pending(Context::getContext().config.get("color.burndown.pending")); + Color color_done(Context::getContext().config.get("color.burndown.done")); + Color color_started(Context::getContext().config.get("color.burndown.started")); // Replace DD, SS, PP with colored strings. std::string::size_type i; - while ((i = _grid.find ("PP")) != std::string::npos) - _grid.replace (i, 2, color_pending.colorize (" ")); + while ((i = _grid.find("PP")) != std::string::npos) + _grid.replace(i, 2, color_pending.colorize(" ")); - while ((i = _grid.find ("SS")) != std::string::npos) - _grid.replace (i, 2, color_started.colorize (" ")); + while ((i = _grid.find("SS")) != std::string::npos) + _grid.replace(i, 2, color_started.colorize(" ")); - while ((i = _grid.find ("DD")) != std::string::npos) - _grid.replace (i, 2, color_done.colorize (" ")); - } - else - { + while ((i = _grid.find("DD")) != std::string::npos) + _grid.replace(i, 2, color_done.colorize(" ")); + } else { // Replace DD, SS, PP with ./+/X strings. std::string::size_type i; - while ((i = _grid.find ("PP")) != std::string::npos) - _grid.replace (i, 2, " X"); + while ((i = _grid.find("PP")) != std::string::npos) _grid.replace(i, 2, " X"); - while ((i = _grid.find ("SS")) != std::string::npos) - _grid.replace (i, 2, " +"); + while ((i = _grid.find("SS")) != std::string::npos) _grid.replace(i, 2, " +"); - while ((i = _grid.find ("DD")) != std::string::npos) - _grid.replace (i, 2, " ."); + while ((i = _grid.find("DD")) != std::string::npos) _grid.replace(i, 2, " ."); } return _grid; @@ -518,213 +472,189 @@ std::string Chart::render () //////////////////////////////////////////////////////////////////////////////// // _grid =~ /\s+$//g -void Chart::optimizeGrid () -{ +void Chart::optimizeGrid() { std::string::size_type ws; - while ((ws = _grid.find (" \n")) != std::string::npos) - { + while ((ws = _grid.find(" \n")) != std::string::npos) { auto non_ws = ws; - while (_grid[non_ws] == ' ') - --non_ws; + while (_grid[non_ws] == ' ') --non_ws; - _grid.replace (non_ws + 1, ws - non_ws + 1, "\n"); + _grid.replace(non_ws + 1, ws - non_ws + 1, "\n"); } } //////////////////////////////////////////////////////////////////////////////// -Datetime Chart::quantize (const Datetime& input, char period) -{ - if (period == 'D') return input.startOfDay (); - if (period == 'W') return input.startOfWeek (); - if (period == 'M') return input.startOfMonth (); +Datetime Chart::quantize(const Datetime& input, char period) { + if (period == 'D') return input.startOfDay(); + if (period == 'W') return input.startOfWeek(); + if (period == 'M') return input.startOfMonth(); return input; } //////////////////////////////////////////////////////////////////////////////// -Datetime Chart::increment (const Datetime& input, char period) -{ +Datetime Chart::increment(const Datetime& input, char period) { // Move to the next period. - int d = input.day (); - int m = input.month (); - int y = input.year (); + int d = input.day(); + int m = input.month(); + int y = input.year(); int days; - switch (period) - { - case 'D': - if (++d > Datetime::daysInMonth (y, m)) - { + switch (period) { + case 'D': + if (++d > Datetime::daysInMonth(y, m)) { + d = 1; + + if (++m == 13) { + m = 1; + ++y; + } + } + break; + + case 'W': + d += 7; + days = Datetime::daysInMonth(y, m); + if (d > days) { + d -= days; + + if (++m == 13) { + m = 1; + ++y; + } + } + break; + + case 'M': d = 1; - - if (++m == 13) - { + if (++m == 13) { m = 1; ++y; } - } - break; - - case 'W': - d += 7; - days = Datetime::daysInMonth (y, m); - if (d > days) - { - d -= days; - - if (++m == 13) - { - m = 1; - ++y; - } - } - break; - - case 'M': - d = 1; - if (++m == 13) - { - m = 1; - ++y; - } - break; + break; } - return Datetime (y, m, d, 0, 0, 0); + return Datetime(y, m, d, 0, 0, 0); } //////////////////////////////////////////////////////////////////////////////// -Datetime Chart::decrement (const Datetime& input, char period) -{ +Datetime Chart::decrement(const Datetime& input, char period) { // Move to the previous period. - int d = input.day (); - int m = input.month (); - int y = input.year (); + int d = input.day(); + int m = input.month(); + int y = input.year(); - switch (period) - { - case 'D': - if (--d == 0) - { - if (--m == 0) - { + switch (period) { + case 'D': + if (--d == 0) { + if (--m == 0) { + m = 12; + --y; + } + + d = Datetime::daysInMonth(y, m); + } + break; + + case 'W': + d -= 7; + if (d < 1) { + if (--m == 0) { + m = 12; + y--; + } + + d += Datetime::daysInMonth(y, m); + } + break; + + case 'M': + d = 1; + if (--m == 0) { m = 12; --y; } - - d = Datetime::daysInMonth (y, m); - } - break; - - case 'W': - d -= 7; - if (d < 1) - { - if (--m == 0) - { - m = 12; - y--; - } - - d += Datetime::daysInMonth (y, m); - } - break; - - case 'M': - d = 1; - if (--m == 0) - { - m = 12; - --y; - } - break; + break; } - return Datetime (y, m, d, 0, 0, 0); + return Datetime(y, m, d, 0, 0, 0); } //////////////////////////////////////////////////////////////////////////////// // Do '_bars[epoch] = Bar' for every bar that may appear on a chart. -void Chart::generateBars () -{ +void Chart::generateBars() { Bar bar; // Determine the last bar date. Datetime cursor; - switch (_period) - { - case 'D': cursor = Datetime ().startOfDay (); break; - case 'W': cursor = Datetime ().startOfWeek (); break; - case 'M': cursor = Datetime ().startOfMonth (); break; + switch (_period) { + case 'D': + cursor = Datetime().startOfDay(); + break; + case 'W': + cursor = Datetime().startOfWeek(); + break; + case 'M': + cursor = Datetime().startOfMonth(); + break; } // Iterate and determine all the other bar dates. char str[12]; - for (int i = 0; i < _estimated_bars; ++i) - { + for (int i = 0; i < _estimated_bars; ++i) { // Create the major and minor labels. - switch (_period) - { - case 'D': // month/day + switch (_period) { + case 'D': // month/day { - std::string month = Datetime::monthName (cursor.month ()); - bar._major_label = month.substr (0, 3); + std::string month = Datetime::monthName(cursor.month()); + bar._major_label = month.substr(0, 3); - snprintf (str, 12, "%02d", cursor.day ()); + snprintf(str, 12, "%02d", cursor.day()); bar._minor_label = str; - } - break; + } break; - case 'W': // year/week - snprintf (str, 12, "%d", cursor.year ()); - bar._major_label = str; + case 'W': // year/week + snprintf(str, 12, "%d", cursor.year()); + bar._major_label = str; - snprintf (str, 12, "%02d", cursor.week ()); - bar._minor_label = str; - break; + snprintf(str, 12, "%02d", cursor.week()); + bar._minor_label = str; + break; - case 'M': // year/month - snprintf (str, 12, "%d", cursor.year ()); - bar._major_label = str; + case 'M': // year/month + snprintf(str, 12, "%d", cursor.year()); + bar._major_label = str; - snprintf (str, 12, "%02d", cursor.month ()); - bar._minor_label = str; - break; + snprintf(str, 12, "%02d", cursor.month()); + bar._minor_label = str; + break; } bar._offset = i; - _bars[cursor.toEpoch ()] = bar; + _bars[cursor.toEpoch()] = bar; // Record the earliest date, for use as a cutoff when scanning data. _earliest = cursor; // Move to the previous period. - cursor = decrement (cursor, _period); + cursor = decrement(cursor, _period); } } //////////////////////////////////////////////////////////////////////////////// -void Chart::maxima () -{ +void Chart::maxima() { _max_value = 0; _max_label = 1; - for (auto& bar : _bars) - { + for (auto& bar : _bars) { // Determine _max_label. - int total = bar.second._pending + - bar.second._started + - bar.second._done + - _carryover_done; + int total = bar.second._pending + bar.second._started + bar.second._done + _carryover_done; // Determine _max_value. - if (total > _max_value) - _max_value = total; + if (total > _max_value) _max_value = total; - int length = (int) log10 ((double) total) + 1; - if (length > _max_label) - _max_label = length; + int length = (int)log10((double)total) + 1; + if (length > _max_label) _max_label = length; } // How many bars can be shown? @@ -735,241 +665,199 @@ void Chart::maxima () //////////////////////////////////////////////////////////////////////////////// // Given the vertical chart area size (graph_height), the largest value // (_max_value), populate a vector of labels for the y axis. -void Chart::yLabels (std::vector & labels) -{ +void Chart::yLabels(std::vector& labels) { // Calculate may Y using a nice algorithm that rounds the data. - int high = burndown_size (_max_value); + int high = burndown_size(_max_value); int half = high / 2; - labels.push_back (0); - labels.push_back (half); - labels.push_back (high); + labels.push_back(0); + labels.push_back(half); + labels.push_back(high); } //////////////////////////////////////////////////////////////////////////////// -void Chart::calculateRates () -{ +void Chart::calculateRates() { // Q: Why is this equation written out as a debug message? // A: People are going to want to know how the rates and the completion date // are calculated. This may also help debugging. std::stringstream peak_message; - peak_message << "Chart::calculateRates Maximum of " - << _peak_count - << " pending tasks on " - << (Datetime (_peak_epoch).toISO ()) - << ", with currently " - << _current_count + peak_message << "Chart::calculateRates Maximum of " << _peak_count << " pending tasks on " + << (Datetime(_peak_epoch).toISO()) << ", with currently " << _current_count << " pending tasks"; - Context::getContext ().debug (peak_message.str ()); + Context::getContext().debug(peak_message.str()); // If there are no current pending tasks, then it is meaningless to find // rates or estimated completion date. - if (_current_count == 0) - return; + if (_current_count == 0) return; // If there is a net fix rate, and the peak was at least three days ago. Datetime now; - Datetime peak (_peak_epoch); - if (_peak_count > _current_count && - (now - peak) > 3 * 86400) - { + Datetime peak(_peak_epoch); + if (_peak_count > _current_count && (now - peak) > 3 * 86400) { // Fixes per second. Not a large number. - auto fix_rate = 1.0 * (_peak_count - _current_count) / (now.toEpoch () - _peak_epoch); + auto fix_rate = 1.0 * (_peak_count - _current_count) / (now.toEpoch() - _peak_epoch); _net_fix_rate = fix_rate * 86400; std::stringstream rate_message; - rate_message << "Chart::calculateRates Net reduction is " - << (_peak_count - _current_count) - << " tasks in " - << Duration (now.toEpoch () - _peak_epoch).formatISO () - << " = " - << _net_fix_rate - << " tasks/d"; - Context::getContext ().debug (rate_message.str ()); + rate_message << "Chart::calculateRates Net reduction is " << (_peak_count - _current_count) + << " tasks in " << Duration(now.toEpoch() - _peak_epoch).formatISO() << " = " + << _net_fix_rate << " tasks/d"; + Context::getContext().debug(rate_message.str()); - Duration delta (static_cast (_current_count / fix_rate)); - Datetime end = now + delta.toTime_t (); + Duration delta(static_cast(_current_count / fix_rate)); + Datetime end = now + delta.toTime_t(); // Prefer dateformat.report over dateformat. - std::string format = Context::getContext ().config.get ("dateformat.report"); - if (format == "") - { - format = Context::getContext ().config.get ("dateformat"); - if (format == "") - format = "Y-M-D"; + std::string format = Context::getContext().config.get("dateformat.report"); + if (format == "") { + format = Context::getContext().config.get("dateformat"); + if (format == "") format = "Y-M-D"; } - _completion = end.toString (format) - + " (" - + delta.formatVague () - + ')'; + _completion = end.toString(format) + " (" + delta.formatVague() + ')'; std::stringstream completion_message; - completion_message << "Chart::calculateRates (" - << _current_count - << " tasks / " - << _net_fix_rate - << ") = " - << delta.format () - << " --> " - << end.toISO (); - Context::getContext ().debug (completion_message.str ()); - } - else - { + completion_message << "Chart::calculateRates (" << _current_count << " tasks / " + << _net_fix_rate << ") = " << delta.format() << " --> " << end.toISO(); + Context::getContext().debug(completion_message.str()); + } else { _completion = "No convergence"; } } //////////////////////////////////////////////////////////////////////////////// -unsigned Chart::round_up_to (unsigned n, unsigned target) -{ - return n + target - (n % target); -} +unsigned Chart::round_up_to(unsigned n, unsigned target) { return n + target - (n % target); } //////////////////////////////////////////////////////////////////////////////// -unsigned Chart::burndown_size (unsigned ntasks) -{ +unsigned Chart::burndown_size(unsigned ntasks) { // Nearest 2 - if (ntasks < 20) - return round_up_to (ntasks, 2); + if (ntasks < 20) return round_up_to(ntasks, 2); // Nearest 10 - if (ntasks < 50) - return round_up_to (ntasks, 10); + if (ntasks < 50) return round_up_to(ntasks, 10); // Nearest 20 - if (ntasks < 100) - return round_up_to (ntasks, 20); + if (ntasks < 100) return round_up_to(ntasks, 20); // Choose the number from here rounded up to the nearest 10% of the next // highest power of 10 or half of power of 10. - const auto count = (unsigned) log10 (static_cast(std::numeric_limits::max ())); + const auto count = (unsigned)log10(static_cast(std::numeric_limits::max())); unsigned half = 500; unsigned full = 1000; // We start at two because we handle 5, 10, 50, and 100 above. - for (unsigned i = 2; i < count; ++i) - { - if (ntasks < half) - return round_up_to (ntasks, half / 10); + for (unsigned i = 2; i < count; ++i) { + if (ntasks < half) return round_up_to(ntasks, half / 10); - if (ntasks < full) - return round_up_to (ntasks, full / 10); + if (ntasks < full) return round_up_to(ntasks, full / 10); half *= 10; full *= 10; } // Round up to max of unsigned. - return std::numeric_limits::max (); + return std::numeric_limits::max(); } //////////////////////////////////////////////////////////////////////////////// -CmdBurndownMonthly::CmdBurndownMonthly () -{ - _keyword = "burndown.monthly"; - _usage = "task burndown.monthly"; - _description = "Shows a graphical burndown chart, by month"; - _read_only = true; - _displays_id = false; - _needs_gc = true; - _uses_context = true; - _accepts_filter = true; +CmdBurndownMonthly::CmdBurndownMonthly() { + _keyword = "burndown.monthly"; + _usage = "task burndown.monthly"; + _description = "Shows a graphical burndown chart, by month"; + _read_only = true; + _displays_id = false; + _needs_gc = true; + _uses_context = true; + _accepts_filter = true; _accepts_modifications = false; _accepts_miscellaneous = false; - _category = Command::Category::graphs; + _category = Command::Category::graphs; } //////////////////////////////////////////////////////////////////////////////// -int CmdBurndownMonthly::execute (std::string& output) -{ +int CmdBurndownMonthly::execute(std::string& output) { int rc = 0; // Scan the pending tasks, applying any filter. - handleUntil (); - handleRecurrence (); + handleUntil(); + handleRecurrence(); Filter filter; - std::vector filtered; - filter.subset (filtered); + std::vector filtered; + filter.subset(filtered); // Create a chart, scan the tasks, then render. - Chart chart ('M'); - chart.scanForPeak (filtered); - chart.scan (filtered); - output = chart.render (); + Chart chart('M'); + chart.scanForPeak(filtered); + chart.scan(filtered); + output = chart.render(); return rc; } //////////////////////////////////////////////////////////////////////////////// -CmdBurndownWeekly::CmdBurndownWeekly () -{ - _keyword = "burndown.weekly"; - _usage = "task burndown.weekly"; - _description = "Shows a graphical burndown chart, by week"; - _read_only = true; - _displays_id = false; - _needs_gc = true; - _uses_context = true; - _accepts_filter = true; +CmdBurndownWeekly::CmdBurndownWeekly() { + _keyword = "burndown.weekly"; + _usage = "task burndown.weekly"; + _description = "Shows a graphical burndown chart, by week"; + _read_only = true; + _displays_id = false; + _needs_gc = true; + _uses_context = true; + _accepts_filter = true; _accepts_modifications = false; _accepts_miscellaneous = false; - _category = Command::Category::graphs; + _category = Command::Category::graphs; } //////////////////////////////////////////////////////////////////////////////// -int CmdBurndownWeekly::execute (std::string& output) -{ +int CmdBurndownWeekly::execute(std::string& output) { int rc = 0; // Scan the pending tasks, applying any filter. - handleUntil (); - handleRecurrence (); + handleUntil(); + handleRecurrence(); Filter filter; - std::vector filtered; - filter.subset (filtered); + std::vector filtered; + filter.subset(filtered); // Create a chart, scan the tasks, then render. - Chart chart ('W'); - chart.scanForPeak (filtered); - chart.scan (filtered); - output = chart.render (); + Chart chart('W'); + chart.scanForPeak(filtered); + chart.scan(filtered); + output = chart.render(); return rc; } //////////////////////////////////////////////////////////////////////////////// -CmdBurndownDaily::CmdBurndownDaily () -{ - _keyword = "burndown.daily"; - _usage = "task burndown.daily"; - _description = "Shows a graphical burndown chart, by day"; - _read_only = true; - _displays_id = false; - _needs_gc = true; - _uses_context = true; - _accepts_filter = true; +CmdBurndownDaily::CmdBurndownDaily() { + _keyword = "burndown.daily"; + _usage = "task burndown.daily"; + _description = "Shows a graphical burndown chart, by day"; + _read_only = true; + _displays_id = false; + _needs_gc = true; + _uses_context = true; + _accepts_filter = true; _accepts_modifications = false; _accepts_miscellaneous = false; - _category = Command::Category::graphs; + _category = Command::Category::graphs; } //////////////////////////////////////////////////////////////////////////////// -int CmdBurndownDaily::execute (std::string& output) -{ +int CmdBurndownDaily::execute(std::string& output) { int rc = 0; // Scan the pending tasks, applying any filter. - handleUntil (); - handleRecurrence (); + handleUntil(); + handleRecurrence(); Filter filter; - std::vector filtered; - filter.subset (filtered); + std::vector filtered; + filter.subset(filtered); // Create a chart, scan the tasks, then render. - Chart chart ('D'); - chart.scanForPeak (filtered); - chart.scan (filtered); - output = chart.render (); + Chart chart('D'); + chart.scanForPeak(filtered); + chart.scan(filtered); + output = chart.render(); return rc; } diff --git a/src/commands/CmdBurndown.h b/src/commands/CmdBurndown.h index 50a2f5336..818b01ea2 100644 --- a/src/commands/CmdBurndown.h +++ b/src/commands/CmdBurndown.h @@ -27,28 +27,26 @@ #ifndef INCLUDED_CMDBURNDOWN #define INCLUDED_CMDBURNDOWN -#include #include -class CmdBurndownMonthly : public Command -{ -public: - CmdBurndownMonthly (); - int execute (std::string&); +#include + +class CmdBurndownMonthly : public Command { + public: + CmdBurndownMonthly(); + int execute(std::string&); }; -class CmdBurndownWeekly : public Command -{ -public: - CmdBurndownWeekly (); - int execute (std::string&); +class CmdBurndownWeekly : public Command { + public: + CmdBurndownWeekly(); + int execute(std::string&); }; -class CmdBurndownDaily : public Command -{ -public: - CmdBurndownDaily (); - int execute (std::string&); +class CmdBurndownDaily : public Command { + public: + CmdBurndownDaily(); + int execute(std::string&); }; #endif diff --git a/src/commands/CmdCalc.cpp b/src/commands/CmdCalc.cpp index bb79a54a4..3ed55e408 100644 --- a/src/commands/CmdCalc.cpp +++ b/src/commands/CmdCalc.cpp @@ -24,53 +24,49 @@ // //////////////////////////////////////////////////////////////////////////////// -#include #include -#include +#include #include +#include //////////////////////////////////////////////////////////////////////////////// -CmdCalc::CmdCalc () -{ - _keyword = "calc"; - _usage = "task calc "; - _description = "Calculator"; - _read_only = true; - _displays_id = false; - _needs_gc = false; - _uses_context = false; - _accepts_filter = false; +CmdCalc::CmdCalc() { + _keyword = "calc"; + _usage = "task calc "; + _description = "Calculator"; + _read_only = true; + _displays_id = false; + _needs_gc = false; + _uses_context = false; + _accepts_filter = false; _accepts_modifications = false; _accepts_miscellaneous = true; - _category = Command::Category::misc; + _category = Command::Category::misc; } //////////////////////////////////////////////////////////////////////////////// -int CmdCalc::execute (std::string& output) -{ +int CmdCalc::execute(std::string& output) { // Configurable infix/postfix - bool infix {true}; - if (Context::getContext ().config.get ("expressions") == "postfix") - infix = false; + bool infix{true}; + if (Context::getContext().config.get("expressions") == "postfix") infix = false; // Create an evaluator with DOM access. Eval e; - e.addSource (domSource); - e.debug (Context::getContext ().config.getBoolean ("debug")); + e.addSource(domSource); + e.debug(Context::getContext().config.getBoolean("debug")); // Compile all the args into one expression. std::string expression; - for (const auto& word : Context::getContext ().cli2.getWords ()) - expression += word + ' '; + for (const auto& word : Context::getContext().cli2.getWords()) expression += word + ' '; // Evaluate according to preference. Variant result; if (infix) - e.evaluateInfixExpression (expression, result); + e.evaluateInfixExpression(expression, result); else - e.evaluatePostfixExpression (expression, result); + e.evaluatePostfixExpression(expression, result); - output = (std::string) result + '\n'; + output = (std::string)result + '\n'; return 0; } diff --git a/src/commands/CmdCalc.h b/src/commands/CmdCalc.h index 442e043b9..930abd45b 100644 --- a/src/commands/CmdCalc.h +++ b/src/commands/CmdCalc.h @@ -27,14 +27,14 @@ #ifndef INCLUDED_CMDCALC #define INCLUDED_CMDCALC -#include #include -class CmdCalc : public Command -{ -public: - CmdCalc (); - int execute (std::string&); +#include + +class CmdCalc : public Command { + public: + CmdCalc(); + int execute(std::string&); }; #endif diff --git a/src/commands/CmdCalendar.cpp b/src/commands/CmdCalendar.cpp index 179ea8a6c..3fae4394d 100644 --- a/src/commands/CmdCalendar.cpp +++ b/src/commands/CmdCalendar.cpp @@ -28,51 +28,50 @@ // cmake.h include header must come first #include -#include -#include -#include #include -#include #include -#include +#include #include -#include -#include #include +#include +#include +#include +#include + +#include +#include //////////////////////////////////////////////////////////////////////////////// -CmdCalendar::CmdCalendar () -{ - _keyword = "calendar"; - _usage = "task calendar [due| |] [y]"; - _description = "Shows a calendar, with due tasks marked"; - _read_only = true; - _displays_id = true; - _needs_gc = true; - _uses_context = false; - _accepts_filter = false; +CmdCalendar::CmdCalendar() { + _keyword = "calendar"; + _usage = "task calendar [due| |] [y]"; + _description = "Shows a calendar, with due tasks marked"; + _read_only = true; + _displays_id = true; + _needs_gc = true; + _uses_context = false; + _accepts_filter = false; _accepts_modifications = false; _accepts_miscellaneous = true; - _category = Command::Category::graphs; + _category = Command::Category::graphs; } //////////////////////////////////////////////////////////////////////////////// -int CmdCalendar::execute (std::string& output) -{ +int CmdCalendar::execute(std::string& output) { int rc = 0; - auto& config = Context::getContext ().config; + auto& config = Context::getContext().config; // Each month requires 28 text columns width. See how many will actually // fit. But if a preference is specified, and it fits, use it. - auto width = Context::getContext ().getWidth (); + auto width = Context::getContext().getWidth(); int preferredMonthsPerLine; - if (config.has ("calendar.monthsperline")) - preferredMonthsPerLine = config.getInteger ("calendar.monthsperline"); + if (config.has("calendar.monthsperline")) + preferredMonthsPerLine = config.getInteger("calendar.monthsperline"); else // Legacy configuration variable value - preferredMonthsPerLine = config.getInteger ("monthsperline"); + preferredMonthsPerLine = config.getInteger("monthsperline"); auto monthsThatFit = width / 26; @@ -81,78 +80,75 @@ int CmdCalendar::execute (std::string& output) monthsPerLine = preferredMonthsPerLine; // Load the pending tasks. - handleUntil (); - handleRecurrence (); - auto tasks = Context::getContext ().tdb2.pending_tasks (); + handleUntil(); + handleRecurrence(); + auto tasks = Context::getContext().tdb2.pending_tasks(); Datetime today; auto getPendingDate = false; auto monthsToDisplay = 1; - auto mFrom = today.month (); - auto yFrom = today.year (); + auto mFrom = today.month(); + auto yFrom = today.year(); auto mTo = mFrom; auto yTo = yFrom; // Defaults. monthsToDisplay = monthsPerLine; - mFrom = today.month (); - yFrom = today.year (); + mFrom = today.month(); + yFrom = today.year(); // Set up a vector of commands (1), for autoComplete. - std::vector commandNames {"calendar"}; + std::vector commandNames{"calendar"}; // Set up a vector of keywords, for autoComplete. - std::vector keywordNames {"due"}; + std::vector keywordNames{"due"}; // Set up a vector of months, for autoComplete. - std::vector monthNames; - for (int i = 1; i <= 12; ++i) - monthNames.push_back (Lexer::lowerCase (Datetime::monthName (i))); + std::vector monthNames; + for (int i = 1; i <= 12; ++i) monthNames.push_back(Lexer::lowerCase(Datetime::monthName(i))); // For autoComplete results. - std::vector matches; + std::vector matches; // Look at all args, regardless of sequence. auto argMonth = 0; auto argYear = 0; auto argWholeYear = false; - for (auto& arg : Context::getContext ().cli2.getWords ()) - { + for (auto& arg : Context::getContext().cli2.getWords()) { // Some version of "calendar". - if (autoComplete (Lexer::lowerCase (arg), commandNames, matches, config.getInteger ("abbreviation.minimum")) == 1) + if (autoComplete(Lexer::lowerCase(arg), commandNames, matches, + config.getInteger("abbreviation.minimum")) == 1) continue; // "due". - else if (autoComplete (Lexer::lowerCase (arg), keywordNames, matches, config.getInteger ("abbreviation.minimum")) == 1) + else if (autoComplete(Lexer::lowerCase(arg), keywordNames, matches, + config.getInteger("abbreviation.minimum")) == 1) getPendingDate = true; // "y". - else if (Lexer::lowerCase (arg) == "y") + else if (Lexer::lowerCase(arg) == "y") argWholeYear = true; // YYYY. - else if (Lexer::isAllDigits (arg) && arg.length () == 4) - argYear = strtol (arg.c_str (), nullptr, 10); + else if (Lexer::isAllDigits(arg) && arg.length() == 4) + argYear = strtol(arg.c_str(), nullptr, 10); // MM. - else if (Lexer::isAllDigits (arg) && arg.length () <= 2) - { - argMonth = strtol (arg.c_str (), nullptr, 10); - if (argMonth < 1 || argMonth > 12) - throw format ("Argument '{1}' is not a valid month.", arg); + else if (Lexer::isAllDigits(arg) && arg.length() <= 2) { + argMonth = strtol(arg.c_str(), nullptr, 10); + if (argMonth < 1 || argMonth > 12) throw format("Argument '{1}' is not a valid month.", arg); } // "January" etc. - else if (autoComplete (Lexer::lowerCase (arg), monthNames, matches, config.getInteger ("abbreviation.minimum")) == 1) - { - argMonth = Datetime::monthOfYear (matches[0]); - if (argMonth == -1) - throw format ("Argument '{1}' is not a valid month.", arg); + else if (autoComplete(Lexer::lowerCase(arg), monthNames, matches, + config.getInteger("abbreviation.minimum")) == 1) { + argMonth = Datetime::monthOfYear(matches[0]); + if (argMonth == -1) throw format("Argument '{1}' is not a valid month.", arg); } else - throw format ("Could not recognize argument '{1}'.", arg); + throw format("Could not recognize argument '{1}'.", arg); } // Supported combinations: @@ -167,56 +163,45 @@ int CmdCalendar::execute (std::string& output) // cal MM YYYY monthsPerLine arg arg false // cal MM YYYY y 12 arg arg false - if (argWholeYear || (argYear && !argMonth && !argWholeYear)) - monthsToDisplay = 12; + if (argWholeYear || (argYear && !argMonth && !argWholeYear)) monthsToDisplay = 12; if (!argMonth && argYear) mFrom = 1; else if (argMonth && argYear) mFrom = argMonth; - if (argYear) - yFrom = argYear; + if (argYear) yFrom = argYear; // Now begin the data subset and rendering. - if (getPendingDate == true) - { + if (getPendingDate == true) { // Find the oldest pending due date. - Datetime oldest (9999, 12, 31); - for (auto& task : tasks) - { - auto status = task.getStatus (); - if (status == Task::pending || status == Task::waiting) - { - if (task.has ("due") && - !task.hasTag ("nocal")) - { - Datetime d (task.get ("due")); + Datetime oldest(9999, 12, 31); + for (auto& task : tasks) { + auto status = task.getStatus(); + if (status == Task::pending || status == Task::waiting) { + if (task.has("due") && !task.hasTag("nocal")) { + Datetime d(task.get("due")); if (d < oldest) oldest = d; } } } // Default to current month if no due date is present - if (oldest != Datetime (9999, 12, 31)) { + if (oldest != Datetime(9999, 12, 31)) { mFrom = oldest.month(); yFrom = oldest.year(); } } - if (config.getBoolean ("calendar.offset")) - { - auto moffset = config.getInteger ("calendar.offset.value") % 12; - auto yoffset = config.getInteger ("calendar.offset.value") / 12; + if (config.getBoolean("calendar.offset")) { + auto moffset = config.getInteger("calendar.offset.value") % 12; + auto yoffset = config.getInteger("calendar.offset.value") / 12; mFrom += moffset; yFrom += yoffset; - if (mFrom < 1) - { + if (mFrom < 1) { mFrom += 12; yFrom--; - } - else if (mFrom > 12) - { + } else if (mFrom > 12) { mFrom -= 12; yFrom++; } @@ -224,8 +209,7 @@ int CmdCalendar::execute (std::string& output) mTo = mFrom + monthsToDisplay - 1; yTo = yFrom; - if (mTo > 12) - { + if (mTo > 12) { mTo -= 12; yTo++; } @@ -236,15 +220,13 @@ int CmdCalendar::execute (std::string& output) std::stringstream out; out << '\n'; - while (yFrom < yTo || (yFrom == yTo && mFrom <= mTo)) - { + while (yFrom < yTo || (yFrom == yTo && mFrom <= mTo)) { auto nextM = mFrom; auto nextY = yFrom; // Print month headers (cheating on the width settings, yes) - for (int i = 0 ; i < monthsPerLine ; i++) - { - auto month = Datetime::monthName (nextM); + for (int i = 0; i < monthsPerLine; i++) { + auto month = Datetime::monthName(nextM); // 12345678901234567890123456 = 26 chars wide // ^^ = center @@ -261,253 +243,207 @@ int CmdCalendar::execute (std::string& output) // +--------------------------+ auto totalWidth = 26; - auto labelWidth = month.length () + 5; // 5 = " 2009" + auto labelWidth = month.length() + 5; // 5 = " 2009" auto leftGap = (totalWidth / 2) - (labelWidth / 2); auto rightGap = totalWidth - leftGap - labelWidth; - out << std::setw (leftGap) << ' ' - << month - << ' ' - << nextY - << std::setw (rightGap) << ' '; + out << std::setw(leftGap) << ' ' << month << ' ' << nextY << std::setw(rightGap) << ' '; - if (++nextM > 12) - { + if (++nextM > 12) { nextM = 1; nextY++; } } out << '\n' - << optionalBlankLine () - << renderMonths (mFrom, yFrom, today, tasks, monthsPerLine) - << '\n'; + << optionalBlankLine() << renderMonths(mFrom, yFrom, today, tasks, monthsPerLine) << '\n'; mFrom += monthsPerLine; - if (mFrom > 12) - { + if (mFrom > 12) { mFrom -= 12; ++yFrom; } } - Color color_today (config.get ("color.calendar.today")); - Color color_due (config.get ("color.calendar.due")); - Color color_duetoday (config.get ("color.calendar.due.today")); - Color color_overdue (config.get ("color.calendar.overdue")); - Color color_weekend (config.get ("color.calendar.weekend")); - Color color_holiday (config.get ("color.calendar.holiday")); - Color color_scheduled (config.get ("color.calendar.scheduled")); - Color color_weeknumber (config.get ("color.calendar.weeknumber")); + Color color_today(config.get("color.calendar.today")); + Color color_due(config.get("color.calendar.due")); + Color color_duetoday(config.get("color.calendar.due.today")); + Color color_overdue(config.get("color.calendar.overdue")); + Color color_weekend(config.get("color.calendar.weekend")); + Color color_holiday(config.get("color.calendar.holiday")); + Color color_scheduled(config.get("color.calendar.scheduled")); + Color color_weeknumber(config.get("color.calendar.weeknumber")); - if (Context::getContext ().color () && config.getBoolean ("calendar.legend")) - { - out << "Legend: " - << color_today.colorize ("today") - << ", " - << color_weekend.colorize ("weekend") + if (Context::getContext().color() && config.getBoolean("calendar.legend")) { + out << "Legend: " << color_today.colorize("today") << ", " << color_weekend.colorize("weekend") << ", "; // If colorizing due dates, print legend - if (config.get ("calendar.details") != "none") - out << color_due.colorize ("due") - << ", " - << color_duetoday.colorize ("due-today") - << ", " - << color_overdue.colorize ("overdue") - << ", " - << color_scheduled.colorize ("scheduled") + if (config.get("calendar.details") != "none") + out << color_due.colorize("due") << ", " << color_duetoday.colorize("due-today") << ", " + << color_overdue.colorize("overdue") << ", " << color_scheduled.colorize("scheduled") << ", "; // If colorizing holidays, print legend - if (config.get ("calendar.holidays") != "none") - out << color_holiday.colorize ("holiday") << ", "; + if (config.get("calendar.holidays") != "none") out << color_holiday.colorize("holiday") << ", "; - out << color_weeknumber.colorize ("weeknumber") - << '.' - << optionalBlankLine () - << '\n'; + out << color_weeknumber.colorize("weeknumber") << '.' << optionalBlankLine() << '\n'; } - if (config.get ("calendar.details") == "full" || config.get ("calendar.holidays") == "full") - { + if (config.get("calendar.details") == "full" || config.get("calendar.holidays") == "full") { --details_mFrom; - if (details_mFrom == 0) - { + if (details_mFrom == 0) { details_mFrom = 12; --details_yFrom; } - int details_dFrom = Datetime::daysInMonth (details_yFrom, details_mFrom); + int details_dFrom = Datetime::daysInMonth(details_yFrom, details_mFrom); ++mTo; - if (mTo == 13) - { + if (mTo == 13) { mTo = 1; ++yTo; } - Datetime date_after (details_yFrom, details_mFrom, details_dFrom); - auto after = date_after.toString (config.get ("dateformat")); + Datetime date_after(details_yFrom, details_mFrom, details_dFrom); + auto after = date_after.toString(config.get("dateformat")); - Datetime date_before (yTo, mTo, 1); - auto before = date_before.toString (config.get ("dateformat")); + Datetime date_before(yTo, mTo, 1); + auto before = date_before.toString(config.get("dateformat")); // Table with due date information - if (config.get ("calendar.details") == "full") - { + if (config.get("calendar.details") == "full") { // Assert that 'report' is a valid report. - auto report = config.get ("calendar.details.report"); - if (Context::getContext ().commands.find (report) == Context::getContext ().commands.end ()) - throw std::string ("The setting 'calendar.details.report' must contain a single report name."); + auto report = config.get("calendar.details.report"); + if (Context::getContext().commands.find(report) == Context::getContext().commands.end()) + throw std::string( + "The setting 'calendar.details.report' must contain a single report name."); // TODO Fix this: cal --> task // calendar --> taskendar // If the executable was "cal" or equivalent, replace it with "task". - auto executable = Context::getContext ().cli2._original_args[0].attribute ("raw"); - auto cal = executable.find ("cal"); - if (cal != std::string::npos) - executable = executable.substr (0, cal) + PACKAGE; + auto executable = Context::getContext().cli2._original_args[0].attribute("raw"); + auto cal = executable.find("cal"); + if (cal != std::string::npos) executable = executable.substr(0, cal) + PACKAGE; - std::vector args; - args.push_back ("rc:" + Context::getContext ().rc_file._data); - args.push_back ("rc.due:0"); - args.push_back ("rc.verbose:label,affected,blank"); - if (Context::getContext ().color ()) - args.push_back ("rc._forcecolor:on"); - args.push_back ("due.after:" + after); - args.push_back ("due.before:" + before); - args.push_back ("-nocal"); - args.push_back (report); + std::vector args; + args.push_back("rc:" + Context::getContext().rc_file._data); + args.push_back("rc.due:0"); + args.push_back("rc.verbose:label,affected,blank"); + if (Context::getContext().color()) args.push_back("rc._forcecolor:on"); + args.push_back("due.after:" + after); + args.push_back("due.before:" + before); + args.push_back("-nocal"); + args.push_back(report); std::string output; - ::execute (executable, args, "", output); + ::execute(executable, args, "", output); out << output; } // Table with holiday information - if (config.get ("calendar.holidays") == "full") - { + if (config.get("calendar.holidays") == "full") { Table holTable; - holTable.width (Context::getContext ().getWidth ()); - holTable.add ("Date"); - holTable.add ("Holiday"); - setHeaderUnderline (holTable); + holTable.width(Context::getContext().getWidth()); + holTable.add("Date"); + holTable.add("Holiday"); + setHeaderUnderline(holTable); - auto dateFormat = config.get ("dateformat.holiday"); + auto dateFormat = config.get("dateformat.holiday"); - std::map > hm; // we need to store multiple holidays per day + std::map> hm; // we need to store multiple holidays per day for (auto& it : config) - if (it.first.substr (0, 8) == "holiday.") - if (it.first.substr (it.first.size () - 4) == "name") - { + if (it.first.substr(0, 8) == "holiday.") + if (it.first.substr(it.first.size() - 4) == "name") { auto holName = it.second; - auto date = config.get ("holiday." + it.first.substr (8, it.first.size () - 13) + ".date"); - auto start = config.get ("holiday." + it.first.substr (8, it.first.size () - 13) + ".start"); - auto end = config.get ("holiday." + it.first.substr (8, it.first.size () - 13) + ".end"); - if (!date.empty ()) - { - Datetime holDate (date.c_str (), dateFormat); + auto date = config.get("holiday." + it.first.substr(8, it.first.size() - 13) + ".date"); + auto start = + config.get("holiday." + it.first.substr(8, it.first.size() - 13) + ".start"); + auto end = config.get("holiday." + it.first.substr(8, it.first.size() - 13) + ".end"); + if (!date.empty()) { + Datetime holDate(date.c_str(), dateFormat); if (date_after < holDate && holDate < date_before) - hm[holDate.toEpoch()].push_back (holName); + hm[holDate.toEpoch()].push_back(holName); } - if (!start.empty () && !end.empty ()) - { - Datetime holStart (start.c_str (), dateFormat); - Datetime holEnd (end.c_str (), dateFormat); + if (!start.empty() && !end.empty()) { + Datetime holStart(start.c_str(), dateFormat); + Datetime holEnd(end.c_str(), dateFormat); if (date_after < holStart && holStart < date_before) - hm[holStart.toEpoch()].push_back ("Start of " + holName); + hm[holStart.toEpoch()].push_back("Start of " + holName); if (date_after < holEnd && holEnd < date_before) - hm[holEnd.toEpoch()].push_back ("End of " + holName); + hm[holEnd.toEpoch()].push_back("End of " + holName); } } - auto format = config.get ("report." + - config.get ("calendar.details.report") + - ".dateformat"); - if (format == "") - format = config.get ("dateformat.report"); - if (format == "") - format = config.get ("dateformat"); + auto format = config.get("report." + config.get("calendar.details.report") + ".dateformat"); + if (format == "") format = config.get("dateformat.report"); + if (format == "") format = config.get("dateformat"); - for (auto& hm_it : hm) - { + for (auto& hm_it : hm) { auto v = hm_it.second; - Datetime hDate (hm_it.first); - auto d = hDate.toString (format); - for (const auto& i : v) - { - auto row = holTable.addRow (); - holTable.set (row, 0, d); - holTable.set (row, 1, i); + Datetime hDate(hm_it.first); + auto d = hDate.toString(format); + for (const auto& i : v) { + auto row = holTable.addRow(); + holTable.set(row, 0, d); + holTable.set(row, 1, i); } } - out << optionalBlankLine () - << holTable.render () - << '\n'; + out << optionalBlankLine() << holTable.render() << '\n'; } } - output = out.str (); + output = out.str(); return rc; } //////////////////////////////////////////////////////////////////////////////// -std::string CmdCalendar::renderMonths ( - int firstMonth, - int firstYear, - const Datetime& today, - std::vector & all, - int monthsPerLine) -{ - - auto& config = Context::getContext ().config; +std::string CmdCalendar::renderMonths(int firstMonth, int firstYear, const Datetime& today, + std::vector& all, int monthsPerLine) { + auto& config = Context::getContext().config; // What day of the week does the user consider the first? - auto weekStart = Datetime::dayOfWeek (config.get ("weekstart")); + auto weekStart = Datetime::dayOfWeek(config.get("weekstart")); if (weekStart != 0 && weekStart != 1) - throw std::string ("The 'weekstart' configuration variable may only contain 'Sunday' or 'Monday'."); + throw std::string( + "The 'weekstart' configuration variable may only contain 'Sunday' or 'Monday'."); // Build table for the number of months to be displayed. Table view; - setHeaderUnderline (view); - view.width (Context::getContext ().getWidth ()); - for (int i = 0 ; i < (monthsPerLine * 8); i += 8) - { - if (weekStart == 1) - { - view.add ("", false); - view.add (utf8_substr (Datetime::dayName (1), 0, 2), false); - view.add (utf8_substr (Datetime::dayName (2), 0, 2), false); - view.add (utf8_substr (Datetime::dayName (3), 0, 2), false); - view.add (utf8_substr (Datetime::dayName (4), 0, 2), false); - view.add (utf8_substr (Datetime::dayName (5), 0, 2), false); - view.add (utf8_substr (Datetime::dayName (6), 0, 2), false); - view.add (utf8_substr (Datetime::dayName (0), 0, 2), false); - } - else - { - view.add ("", false); - view.add (utf8_substr (Datetime::dayName (0), 0, 2), false); - view.add (utf8_substr (Datetime::dayName (1), 0, 2), false); - view.add (utf8_substr (Datetime::dayName (2), 0, 2), false); - view.add (utf8_substr (Datetime::dayName (3), 0, 2), false); - view.add (utf8_substr (Datetime::dayName (4), 0, 2), false); - view.add (utf8_substr (Datetime::dayName (5), 0, 2), false); - view.add (utf8_substr (Datetime::dayName (6), 0, 2), false); + setHeaderUnderline(view); + view.width(Context::getContext().getWidth()); + for (int i = 0; i < (monthsPerLine * 8); i += 8) { + if (weekStart == 1) { + view.add("", false); + view.add(utf8_substr(Datetime::dayName(1), 0, 2), false); + view.add(utf8_substr(Datetime::dayName(2), 0, 2), false); + view.add(utf8_substr(Datetime::dayName(3), 0, 2), false); + view.add(utf8_substr(Datetime::dayName(4), 0, 2), false); + view.add(utf8_substr(Datetime::dayName(5), 0, 2), false); + view.add(utf8_substr(Datetime::dayName(6), 0, 2), false); + view.add(utf8_substr(Datetime::dayName(0), 0, 2), false); + } else { + view.add("", false); + view.add(utf8_substr(Datetime::dayName(0), 0, 2), false); + view.add(utf8_substr(Datetime::dayName(1), 0, 2), false); + view.add(utf8_substr(Datetime::dayName(2), 0, 2), false); + view.add(utf8_substr(Datetime::dayName(3), 0, 2), false); + view.add(utf8_substr(Datetime::dayName(4), 0, 2), false); + view.add(utf8_substr(Datetime::dayName(5), 0, 2), false); + view.add(utf8_substr(Datetime::dayName(6), 0, 2), false); } } // At most, we need 6 rows. - view.addRow (); - view.addRow (); - view.addRow (); - view.addRow (); - view.addRow (); - view.addRow (); + view.addRow(); + view.addRow(); + view.addRow(); + view.addRow(); + view.addRow(); + view.addRow(); // Set number of days per month, months to render, and years to render. std::vector years; @@ -515,153 +451,126 @@ std::string CmdCalendar::renderMonths ( std::vector daysInMonth; int thisYear = firstYear; int thisMonth = firstMonth; - for (int i = 0 ; i < monthsPerLine ; i++) - { - if (thisMonth < 13) - { - years.push_back (thisYear); - } - else - { + for (int i = 0; i < monthsPerLine; i++) { + if (thisMonth < 13) { + years.push_back(thisYear); + } else { thisMonth -= 12; - years.push_back (++thisYear); + years.push_back(++thisYear); } - months.push_back (thisMonth); - daysInMonth.push_back (Datetime::daysInMonth (thisYear, thisMonth++)); + months.push_back(thisMonth); + daysInMonth.push_back(Datetime::daysInMonth(thisYear, thisMonth++)); } auto row = 0; - Color color_today (config.get ("color.calendar.today")); - Color color_due (config.get ("color.calendar.due")); - Color color_duetoday (config.get ("color.calendar.due.today")); - Color color_overdue (config.get ("color.calendar.overdue")); - Color color_weekend (config.get ("color.calendar.weekend")); - Color color_holiday (config.get ("color.calendar.holiday")); - Color color_scheduled (config.get ("color.calendar.scheduled")); - Color color_weeknumber (config.get ("color.calendar.weeknumber")); + Color color_today(config.get("color.calendar.today")); + Color color_due(config.get("color.calendar.due")); + Color color_duetoday(config.get("color.calendar.due.today")); + Color color_overdue(config.get("color.calendar.overdue")); + Color color_weekend(config.get("color.calendar.weekend")); + Color color_holiday(config.get("color.calendar.holiday")); + Color color_scheduled(config.get("color.calendar.scheduled")); + Color color_weeknumber(config.get("color.calendar.weeknumber")); // Loop through months to be added on this line. - for (int mpl = 0; mpl < monthsPerLine ; mpl++) - { + for (int mpl = 0; mpl < monthsPerLine; mpl++) { // Reset row counter for subsequent months - if (mpl != 0) - row = 0; + if (mpl != 0) row = 0; // Loop through days in month and add to table. - for (int d = 1; d <= daysInMonth[mpl]; ++d) - { - Datetime date (years[mpl], months[mpl], d); - auto dow = date.dayOfWeek (); - auto woy = date.week (); + for (int d = 1; d <= daysInMonth[mpl]; ++d) { + Datetime date(years[mpl], months[mpl], d); + auto dow = date.dayOfWeek(); + auto woy = date.week(); - if (config.getBoolean ("displayweeknumber")) - view.set (row, - (8 * mpl), - // Make sure the week number is always 4 columns, space-padded. - format ((woy < 10 ? " {1}" : " {1}"), woy), - color_weeknumber); + if (config.getBoolean("displayweeknumber")) + view.set(row, (8 * mpl), + // Make sure the week number is always 4 columns, space-padded. + format((woy < 10 ? " {1}" : " {1}"), woy), color_weeknumber); // Calculate column id. auto thisCol = dow + // 0 = Sunday (weekStart == 1 ? 0 : 1) + // Offset for weekStart (8 * mpl); // Columns in 1 month - if (thisCol == (8 * mpl)) - thisCol += 7; + if (thisCol == (8 * mpl)) thisCol += 7; - view.set (row, thisCol, d); + view.set(row, thisCol, d); - if (Context::getContext ().color ()) - { + if (Context::getContext().color()) { Color cellColor; // colorize weekends - if (dow == 0 || dow == 6) - cellColor.blend (color_weekend); + if (dow == 0 || dow == 6) cellColor.blend(color_weekend); // colorize holidays - if (config.get ("calendar.holidays") != "none") - { - auto dateFormat = config.get ("dateformat.holiday"); - for (auto& hol : config) - { - if (hol.first.substr (0, 8) == "holiday.") - { - if (hol.first.substr (hol.first.size () - 4) == "date") - { + if (config.get("calendar.holidays") != "none") { + auto dateFormat = config.get("dateformat.holiday"); + for (auto& hol : config) { + if (hol.first.substr(0, 8) == "holiday.") { + if (hol.first.substr(hol.first.size() - 4) == "date") { auto value = hol.second; - Datetime holDate (value.c_str (), dateFormat); - if (holDate.sameDay (date)) - cellColor.blend (color_holiday); + Datetime holDate(value.c_str(), dateFormat); + if (holDate.sameDay(date)) cellColor.blend(color_holiday); } - if (hol.first.substr (hol.first.size () - 5) == "start" && - config.has ("holiday." + hol.first.substr (8, hol.first.size () - 14) + ".end")) - { + if (hol.first.substr(hol.first.size() - 5) == "start" && + config.has("holiday." + hol.first.substr(8, hol.first.size() - 14) + ".end")) { auto start = hol.second; - auto end = config.get ("holiday." + hol.first.substr (8, hol.first.size () - 14) + ".end"); - Datetime holStart (start.c_str (), dateFormat); - Datetime holEnd (end.c_str (), dateFormat); - if (holStart <= date && date <= holEnd) - cellColor.blend (color_holiday); + auto end = + config.get("holiday." + hol.first.substr(8, hol.first.size() - 14) + ".end"); + Datetime holStart(start.c_str(), dateFormat); + Datetime holEnd(end.c_str(), dateFormat); + if (holStart <= date && date <= holEnd) cellColor.blend(color_holiday); } } } } // colorize today - if (today.sameDay (date)) - cellColor.blend (color_today); + if (today.sameDay(date)) cellColor.blend(color_today); // colorize due and scheduled tasks - if (config.get ("calendar.details") != "none") - { - config.set ("due", 0); - config.set ("scheduled", 0); + if (config.get("calendar.details") != "none") { + config.set("due", 0); + config.set("scheduled", 0); // if a date has a task that is due on that day, the due color // takes precedence over the scheduled color bool coloredWithDue = false; - for (auto& task : all) - { - auto status = task.getStatus (); - if ((status == Task::pending || - status == Task::waiting ) && - !task.hasTag ("nocal")) - { - if(task.has("scheduled") && !coloredWithDue) { - std::string scheduled = task.get ("scheduled"); - Datetime scheduleddmy (strtoll (scheduled.c_str(), nullptr, 10)); + for (auto& task : all) { + auto status = task.getStatus(); + if ((status == Task::pending || status == Task::waiting) && !task.hasTag("nocal")) { + if (task.has("scheduled") && !coloredWithDue) { + std::string scheduled = task.get("scheduled"); + Datetime scheduleddmy(strtoll(scheduled.c_str(), nullptr, 10)); - if (scheduleddmy.sameDay (date)) - { + if (scheduleddmy.sameDay(date)) { cellColor.blend(color_scheduled); } } - if(task.has("due")) { - std::string due = task.get ("due"); - Datetime duedmy (strtoll (due.c_str(), nullptr, 10)); + if (task.has("due")) { + std::string due = task.get("due"); + Datetime duedmy(strtoll(due.c_str(), nullptr, 10)); - if (duedmy.sameDay (date)) - { + if (duedmy.sameDay(date)) { coloredWithDue = true; - switch (task.getDateState ("due")) - { - case Task::dateNotDue: - break; + switch (task.getDateState("due")) { + case Task::dateNotDue: + break; - case Task::dateAfterToday: - cellColor.blend (color_due); - break; + case Task::dateAfterToday: + cellColor.blend(color_due); + break; - case Task::dateLaterToday: - cellColor.blend (color_duetoday); - break; + case Task::dateLaterToday: + cellColor.blend(color_duetoday); + break; - case Task::dateEarlierToday: - case Task::dateBeforeToday: - cellColor.blend (color_overdue); - break; + case Task::dateEarlierToday: + case Task::dateBeforeToday: + cellColor.blend(color_overdue); + break; } } } @@ -669,19 +578,17 @@ std::string CmdCalendar::renderMonths ( } } - view.set (row, thisCol, cellColor); + view.set(row, thisCol, cellColor); } // Check for end of week, and... int eow = 6; - if (weekStart == 1) - eow = 0; - if (dow == eow && d < daysInMonth[mpl]) - row++; + if (weekStart == 1) eow = 0; + if (dow == eow && d < daysInMonth[mpl]) row++; } } - return view.render (); + return view.render(); } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/commands/CmdCalendar.h b/src/commands/CmdCalendar.h index d2645ef3b..afd1f9d27 100644 --- a/src/commands/CmdCalendar.h +++ b/src/commands/CmdCalendar.h @@ -27,20 +27,20 @@ #ifndef INCLUDED_CMDCALENDAR #define INCLUDED_CMDCALENDAR -#include -#include +#include #include #include -#include -class CmdCalendar : public Command -{ -public: - CmdCalendar (); - int execute (std::string&); +#include +#include -private: - std::string renderMonths (int, int, const Datetime&, std::vector &, int); +class CmdCalendar : public Command { + public: + CmdCalendar(); + int execute(std::string&); + + private: + std::string renderMonths(int, int, const Datetime&, std::vector&, int); }; #endif diff --git a/src/commands/CmdColor.cpp b/src/commands/CmdColor.cpp index 8ce3c576a..bb0d7f548 100644 --- a/src/commands/CmdColor.cpp +++ b/src/commands/CmdColor.cpp @@ -28,161 +28,137 @@ // cmake.h include header must come first #include -#include -#include -#include -#include #include +#include +#include #include +#include #include +#include + //////////////////////////////////////////////////////////////////////////////// -CmdColor::CmdColor () -{ - _keyword = "colors"; - _usage = "task colors [sample | legend]"; - _description = "All colors, a sample, or a legend"; - _read_only = true; - _displays_id = false; - _needs_gc = false; - _uses_context = false; - _accepts_filter = false; +CmdColor::CmdColor() { + _keyword = "colors"; + _usage = "task colors [sample | legend]"; + _description = "All colors, a sample, or a legend"; + _read_only = true; + _displays_id = false; + _needs_gc = false; + _uses_context = false; + _accepts_filter = false; _accepts_modifications = false; _accepts_miscellaneous = true; - _category = Command::Category::misc; + _category = Command::Category::misc; } //////////////////////////////////////////////////////////////////////////////// -int CmdColor::execute (std::string& output) -{ +int CmdColor::execute(std::string& output) { int rc = 0; // Get the non-attribute, non-fancy command line arguments. auto legend = false; - auto words = Context::getContext ().cli2.getWords (); + auto words = Context::getContext().cli2.getWords(); for (auto& word : words) - if (closeEnough ("legend", word)) - legend = true; + if (closeEnough("legend", word)) legend = true; std::stringstream out; - if (Context::getContext ().color ()) - { + if (Context::getContext().color()) { // If the description contains 'legend', show all the colors currently in // use. - if (legend) - { + if (legend) { out << "\nHere are the colors currently in use:\n"; Table view; - view.width (Context::getContext ().getWidth ()); - if (Context::getContext ().config.getBoolean ("color")) - view.forceColor (); - view.add ("Color"); - view.add ("Definition"); + view.width(Context::getContext().getWidth()); + if (Context::getContext().config.getBoolean("color")) view.forceColor(); + view.add("Color"); + view.add("Definition"); - for (auto& item : Context::getContext ().config) - { + for (auto& item : Context::getContext().config) { // Skip items with 'color' in their name, that are not referring to // actual colors. - if (item.first != "_forcecolor" && - item.first != "color" && - item.first.find ("color") == 0) - { - Color color (Context::getContext ().config.get (item.first)); - int row = view.addRow (); - view.set (row, 0, item.first, color); - view.set (row, 1, item.second, color); + if (item.first != "_forcecolor" && item.first != "color" && item.first.find("color") == 0) { + Color color(Context::getContext().config.get(item.first)); + int row = view.addRow(); + view.set(row, 0, item.first, color); + view.set(row, 1, item.second, color); } } - out << view.render () - << '\n'; + out << view.render() << '\n'; } // If there is something in the description, then assume that is a color, // and display it as a sample. - else if (words.size ()) - { - Color one ("black on bright yellow"); - Color two ("underline cyan on bright blue"); - Color three ("color214 on color202"); - Color four ("rgb150 on rgb020"); - Color five ("underline grey10 on grey3"); - Color six ("red on color173"); + else if (words.size()) { + Color one("black on bright yellow"); + Color two("underline cyan on bright blue"); + Color three("color214 on color202"); + Color four("rgb150 on rgb020"); + Color five("underline grey10 on grey3"); + Color six("red on color173"); std::string swatch; - for (auto word = words.begin (); word != words.end (); ++word) - { - if (word != words.begin ()) - swatch += ' '; + for (auto word = words.begin(); word != words.end(); ++word) { + if (word != words.begin()) swatch += ' '; swatch += *word; } - Color sample (swatch); + Color sample(swatch); out << '\n' << "Use this command to see how colors are displayed by your terminal.\n" << "\n\n" << "16-color usage (supports underline, bold text, bright background):\n" - << " " << one.colorize ("task color black on bright yellow") << '\n' - << " " << two.colorize ("task color underline cyan on bright blue") << '\n' + << " " << one.colorize("task color black on bright yellow") << '\n' + << " " << two.colorize("task color underline cyan on bright blue") << '\n' << '\n' << "256-color usage (supports underline):\n" - << " " << three.colorize ("task color color214 on color202") << '\n' - << " " << four.colorize ("task color rgb150 on rgb020") << '\n' - << " " << five.colorize ("task color underline grey10 on grey3") << '\n' - << " " << six.colorize ("task color red on color173") << '\n' + << " " << three.colorize("task color color214 on color202") << '\n' + << " " << four.colorize("task color rgb150 on rgb020") << '\n' + << " " << five.colorize("task color underline grey10 on grey3") << '\n' + << " " << six.colorize("task color red on color173") << '\n' << '\n' << "Your sample:\n\n" - << " " << sample.colorize ("task color " + swatch) << "\n\n"; + << " " << sample.colorize("task color " + swatch) << "\n\n"; } // Show all supported colors. Possibly show some unsupported ones too. - else - { + else { out << '\n' << "Basic colors\n" - << ' ' << Color::colorize (" black ", "black") - << ' ' << Color::colorize (" red ", "red") - << ' ' << Color::colorize (" blue ", "blue") - << ' ' << Color::colorize (" green ", "green") - << ' ' << Color::colorize (" magenta ", "magenta") - << ' ' << Color::colorize (" cyan ", "cyan") - << ' ' << Color::colorize (" yellow ", "yellow") - << ' ' << Color::colorize (" white ", "white") - << '\n' - << ' ' << Color::colorize (" black ", "white on black") - << ' ' << Color::colorize (" red ", "white on red") - << ' ' << Color::colorize (" blue ", "white on blue") - << ' ' << Color::colorize (" green ", "black on green") - << ' ' << Color::colorize (" magenta ", "black on magenta") - << ' ' << Color::colorize (" cyan ", "black on cyan") - << ' ' << Color::colorize (" yellow ", "black on yellow") - << ' ' << Color::colorize (" white ", "black on white") - << "\n\n"; + << ' ' << Color::colorize(" black ", "black") << ' ' << Color::colorize(" red ", "red") + << ' ' << Color::colorize(" blue ", "blue") << ' ' << Color::colorize(" green ", "green") + << ' ' << Color::colorize(" magenta ", "magenta") << ' ' + << Color::colorize(" cyan ", "cyan") << ' ' << Color::colorize(" yellow ", "yellow") + << ' ' << Color::colorize(" white ", "white") << '\n' + << ' ' << Color::colorize(" black ", "white on black") << ' ' + << Color::colorize(" red ", "white on red") << ' ' + << Color::colorize(" blue ", "white on blue") << ' ' + << Color::colorize(" green ", "black on green") << ' ' + << Color::colorize(" magenta ", "black on magenta") << ' ' + << Color::colorize(" cyan ", "black on cyan") << ' ' + << Color::colorize(" yellow ", "black on yellow") << ' ' + << Color::colorize(" white ", "black on white") << "\n\n"; out << "Effects\n" - << ' ' << Color::colorize (" red ", "red") - << ' ' << Color::colorize (" bold red ", "bold red") - << ' ' << Color::colorize (" underline on blue ", "underline on blue") - << ' ' << Color::colorize (" on green ", "black on green") - << ' ' << Color::colorize (" on bright green ", "black on bright green") - << ' ' << Color::colorize (" inverse ", "inverse") - << "\n\n"; + << ' ' << Color::colorize(" red ", "red") << ' ' + << Color::colorize(" bold red ", "bold red") << ' ' + << Color::colorize(" underline on blue ", "underline on blue") << ' ' + << Color::colorize(" on green ", "black on green") << ' ' + << Color::colorize(" on bright green ", "black on bright green") << ' ' + << Color::colorize(" inverse ", "inverse") << "\n\n"; // 16 system colors. - out << "color0 - color15" - << '\n' - << " 0 1 2 . . .\n"; - for (int r = 0; r < 2; ++r) - { + out << "color0 - color15" << '\n' << " 0 1 2 . . .\n"; + for (int r = 0; r < 2; ++r) { out << " "; - for (int c = 0; c < 8; ++c) - { + for (int c = 0; c < 8; ++c) { std::stringstream s; - s << "on color" << (r*8 + c); - out << Color::colorize (" ", s.str ()); + s << "on color" << (r * 8 + c); + out << Color::colorize(" ", s.str()); } out << '\n'; @@ -191,43 +167,40 @@ int CmdColor::execute (std::string& output) out << " . . . 15\n\n"; // Color cube. - out << "Color cube rgb" - << Color::colorize ("0", "bold red") - << Color::colorize ("0", "bold green") - << Color::colorize ("0", "bold blue") - << " - rgb" - << Color::colorize ("5", "bold red") - << Color::colorize ("5", "bold green") - << Color::colorize ("5", "bold blue") - << " (also color16 - color231)" + out << "Color cube rgb" << Color::colorize("0", "bold red") + << Color::colorize("0", "bold green") << Color::colorize("0", "bold blue") << " - rgb" + << Color::colorize("5", "bold red") << Color::colorize("5", "bold green") + << Color::colorize("5", "bold blue") << " (also color16 - color231)" << '\n' + << " " + << Color::colorize( + "0 " + "1 " + "2 " + "3 " + "4 " + "5", + "bold red") << '\n' - << " " << Color::colorize ("0 " - "1 " - "2 " - "3 " - "4 " - "5", "bold red") - << '\n' - << " " << Color::colorize ("0 1 2 3 4 5 " - "0 1 2 3 4 5 " - "0 1 2 3 4 5 " - "0 1 2 3 4 5 " - "0 1 2 3 4 5 " - "0 1 2 3 4 5", "bold blue") + << " " + << Color::colorize( + "0 1 2 3 4 5 " + "0 1 2 3 4 5 " + "0 1 2 3 4 5 " + "0 1 2 3 4 5 " + "0 1 2 3 4 5 " + "0 1 2 3 4 5", + "bold blue") << '\n'; - char label [12]; - for (int g = 0; g < 6; ++g) - { - snprintf (label, 12, " %d", g); - out << Color::colorize (label, "bold green"); - for (int r = 0; r < 6; ++r) - { - for (int b = 0; b < 6; ++b) - { + char label[12]; + for (int g = 0; g < 6; ++g) { + snprintf(label, 12, " %d", g); + out << Color::colorize(label, "bold green"); + for (int r = 0; r < 6; ++r) { + for (int b = 0; b < 6; ++b) { std::stringstream s; s << "on rgb" << r << g << b; - out << Color::colorize (" ", s.str ()); + out << Color::colorize(" ", s.str()); } out << ' '; @@ -242,25 +215,23 @@ int CmdColor::execute (std::string& output) out << "Gray ramp gray0 - gray23 (also color232 - color255)\n" << " 0 1 2 . . . . . . 23\n" << " "; - for (int g = 0; g < 24; ++g) - { + for (int g = 0; g < 24; ++g) { std::stringstream s; s << "on gray" << g; - out << Color::colorize (" ", s.str ()); + out << Color::colorize(" ", s.str()); } out << "\n\n" << "Try running 'task color white on red'.\n" << '\n'; } - } - else - { - out << "Color is currently turned off in your .taskrc file. To enable color, remove the line 'color=off', or change the 'off' to 'on'.\n"; + } else { + out << "Color is currently turned off in your .taskrc file. To enable color, remove the line " + "'color=off', or change the 'off' to 'on'.\n"; rc = 1; } - output = out.str (); + output = out.str(); return rc; } diff --git a/src/commands/CmdColor.h b/src/commands/CmdColor.h index 34c6cd674..785de4a74 100644 --- a/src/commands/CmdColor.h +++ b/src/commands/CmdColor.h @@ -27,14 +27,14 @@ #ifndef INCLUDED_CMDCOLOR #define INCLUDED_CMDCOLOR -#include #include -class CmdColor : public Command -{ -public: - CmdColor (); - int execute (std::string&); +#include + +class CmdColor : public Command { + public: + CmdColor(); + int execute(std::string&); }; #endif diff --git a/src/commands/CmdColumns.cpp b/src/commands/CmdColumns.cpp index 6502882df..2b2e32bfb 100644 --- a/src/commands/CmdColumns.cpp +++ b/src/commands/CmdColumns.cpp @@ -28,123 +28,114 @@ // cmake.h include header must come first #include -#include +#include #include #include -#include +#include #include #include -#include + +#include //////////////////////////////////////////////////////////////////////////////// -CmdColumns::CmdColumns () -{ - _keyword = "columns"; - _usage = "task columns [substring]"; - _description = "All supported columns and formatting styles"; - _read_only = true; - _displays_id = false; - _needs_gc = false; - _uses_context = false; - _accepts_filter = false; +CmdColumns::CmdColumns() { + _keyword = "columns"; + _usage = "task columns [substring]"; + _description = "All supported columns and formatting styles"; + _read_only = true; + _displays_id = false; + _needs_gc = false; + _uses_context = false; + _accepts_filter = false; _accepts_modifications = false; _accepts_miscellaneous = true; - _category = Command::Category::config; + _category = Command::Category::config; } //////////////////////////////////////////////////////////////////////////////// -int CmdColumns::execute (std::string& output) -{ +int CmdColumns::execute(std::string& output) { // Obtain the arguments from the description. That way, things like '--' // have already been handled. - auto words = Context::getContext ().cli2.getWords (); - if (words.size () > 1) - throw std::string ("You can only specify one search string."); + auto words = Context::getContext().cli2.getWords(); + if (words.size() > 1) throw std::string("You can only specify one search string."); // Include all columns in the table. - std::vector names; - for (const auto& col : Context::getContext ().columns) - names.push_back (col.first); + std::vector names; + for (const auto& col : Context::getContext().columns) names.push_back(col.first); - std::sort (names.begin (), names.end ()); + std::sort(names.begin(), names.end()); // Render a list of column names, formats and examples. Table formats; - formats.width (Context::getContext ().getWidth ()); - formats.add ("Columns"); - formats.add ("Type"); - formats.add ("Modifiable"); - formats.add ("Supported Formats"); - formats.add ("Example"); - setHeaderUnderline (formats); + formats.width(Context::getContext().getWidth()); + formats.add("Columns"); + formats.add("Type"); + formats.add("Modifiable"); + formats.add("Supported Formats"); + formats.add("Example"); + setHeaderUnderline(formats); - for (const auto& name : names) - { - if (words.size () == 0 || - find (name, words[0], false) != std::string::npos) - { - auto styles = Context::getContext ().columns[name]->styles (); - auto examples = Context::getContext ().columns[name]->examples (); + for (const auto& name : names) { + if (words.size() == 0 || find(name, words[0], false) != std::string::npos) { + auto styles = Context::getContext().columns[name]->styles(); + auto examples = Context::getContext().columns[name]->examples(); - for (unsigned int i = 0; i < styles.size (); ++i) - { - auto row = formats.addRow (); - formats.set (row, 0, i == 0 ? name : ""); - formats.set (row, 1, i == 0 ? Context::getContext ().columns[name]->type () : ""); - formats.set (row, 2, i == 0 ? (Context::getContext ().columns[name]->modifiable () ? "Modifiable" : "Read Only") : ""); - formats.set (row, 3, styles[i] + (i == 0 ? "*" : "")); - formats.set (row, 4, i < examples.size () ? examples[i] : ""); + for (unsigned int i = 0; i < styles.size(); ++i) { + auto row = formats.addRow(); + formats.set(row, 0, i == 0 ? name : ""); + formats.set(row, 1, i == 0 ? Context::getContext().columns[name]->type() : ""); + formats.set(row, 2, + i == 0 ? (Context::getContext().columns[name]->modifiable() ? "Modifiable" + : "Read Only") + : ""); + formats.set(row, 3, styles[i] + (i == 0 ? "*" : "")); + formats.set(row, 4, i < examples.size() ? examples[i] : ""); } } } - auto row = formats.addRow (); - formats.set (row, 0, ""); - formats.set (row, 1, ""); - formats.set (row, 2, "Modifiable"); - formats.set (row, 3, "default*"); + auto row = formats.addRow(); + formats.set(row, 0, ""); + formats.set(row, 1, ""); + formats.set(row, 2, "Modifiable"); + formats.set(row, 3, "default*"); - row = formats.addRow (); - formats.set (row, 0, ""); - formats.set (row, 3, "indicator"); + row = formats.addRow(); + formats.set(row, 0, ""); + formats.set(row, 3, "indicator"); - output = optionalBlankLine () - + formats.render () - + '\n' - + "* Means default format, and therefore optional. For example, 'due' and 'due.formatted' are equivalent.\n"; + output = optionalBlankLine() + formats.render() + '\n' + + "* Means default format, and therefore optional. For example, 'due' and " + "'due.formatted' are equivalent.\n"; return 0; } //////////////////////////////////////////////////////////////////////////////// -CmdCompletionColumns::CmdCompletionColumns () -{ - _keyword = "_columns"; - _usage = "task _columns"; - _description = "Displays only a list of supported columns"; - _read_only = true; - _displays_id = false; - _needs_gc = false; - _uses_context = false; - _accepts_filter = false; +CmdCompletionColumns::CmdCompletionColumns() { + _keyword = "_columns"; + _usage = "task _columns"; + _description = "Displays only a list of supported columns"; + _read_only = true; + _displays_id = false; + _needs_gc = false; + _uses_context = false; + _accepts_filter = false; _accepts_modifications = false; _accepts_miscellaneous = false; - _category = Command::Category::internal; + _category = Command::Category::internal; } //////////////////////////////////////////////////////////////////////////////// -int CmdCompletionColumns::execute (std::string& output) -{ +int CmdCompletionColumns::execute(std::string& output) { // Include all columns. - std::vector names; - for (const auto& col : Context::getContext ().columns) - names.push_back (col.first); + std::vector names; + for (const auto& col : Context::getContext().columns) names.push_back(col.first); - std::sort (names.begin (), names.end ()); + std::sort(names.begin(), names.end()); // Render only the column names. - for (const auto& name : names) - output += name + '\n'; + for (const auto& name : names) output += name + '\n'; return 0; } diff --git a/src/commands/CmdColumns.h b/src/commands/CmdColumns.h index 9d4d0cedc..7a12caf13 100644 --- a/src/commands/CmdColumns.h +++ b/src/commands/CmdColumns.h @@ -27,21 +27,20 @@ #ifndef INCLUDED_CMDCOLUMNS #define INCLUDED_CMDCOLUMNS -#include #include -class CmdColumns : public Command -{ -public: - CmdColumns (); - int execute (std::string&); +#include + +class CmdColumns : public Command { + public: + CmdColumns(); + int execute(std::string&); }; -class CmdCompletionColumns : public Command -{ -public: - CmdCompletionColumns (); - int execute (std::string&); +class CmdCompletionColumns : public Command { + public: + CmdCompletionColumns(); + int execute(std::string&); }; #endif diff --git a/src/commands/CmdCommands.cpp b/src/commands/CmdCommands.cpp index 6382d5d52..4676f57ae 100644 --- a/src/commands/CmdCommands.cpp +++ b/src/commands/CmdCommands.cpp @@ -28,145 +28,128 @@ // cmake.h include header must come first #include -#include -#include -#include +#include #include #include -#include +#include #include +#include +#include + //////////////////////////////////////////////////////////////////////////////// -CmdCommands::CmdCommands () -{ - _keyword = "commands"; - _usage = "task commands"; - _description = "Generates a list of all commands, with behavior details"; - _read_only = true; - _displays_id = false; - _needs_gc = false; - _uses_context = false; - _accepts_filter = false; +CmdCommands::CmdCommands() { + _keyword = "commands"; + _usage = "task commands"; + _description = "Generates a list of all commands, with behavior details"; + _read_only = true; + _displays_id = false; + _needs_gc = false; + _uses_context = false; + _accepts_filter = false; _accepts_modifications = false; _accepts_miscellaneous = false; - _category = Command::Category::metadata; + _category = Command::Category::metadata; } //////////////////////////////////////////////////////////////////////////////// -int CmdCommands::execute (std::string& output) -{ +int CmdCommands::execute(std::string& output) { Table view; - view.width (Context::getContext ().getWidth ()); - view.add ("Command"); - view.add ("Category"); - view.add ("R/W", false); - view.add ("ID", false); - view.add ("GC", false); - view.add ("Context", false); - view.add ("Filter", false); - view.add ("Mods", false); - view.add ("Misc", false); - view.add ("Description"); - view.leftMargin (Context::getContext ().config.getInteger ("indent.report")); - view.extraPadding (Context::getContext ().config.getInteger ("row.padding")); - view.intraPadding (Context::getContext ().config.getInteger ("column.padding")); - setHeaderUnderline (view); + view.width(Context::getContext().getWidth()); + view.add("Command"); + view.add("Category"); + view.add("R/W", false); + view.add("ID", false); + view.add("GC", false); + view.add("Context", false); + view.add("Filter", false); + view.add("Mods", false); + view.add("Misc", false); + view.add("Description"); + view.leftMargin(Context::getContext().config.getInteger("indent.report")); + view.extraPadding(Context::getContext().config.getInteger("row.padding")); + view.intraPadding(Context::getContext().config.getInteger("column.padding")); + setHeaderUnderline(view); - for (auto& command : Context::getContext ().commands) - { - auto row = view.addRow (); - view.set (row, 0, command.first); - view.set (row, 1, Command::categoryNames.at (command.second->category ())); + for (auto& command : Context::getContext().commands) { + auto row = view.addRow(); + view.set(row, 0, command.first); + view.set(row, 1, Command::categoryNames.at(command.second->category())); - if (command.second->read_only ()) - view.set (row, 2, "RO"); + if (command.second->read_only()) + view.set(row, 2, "RO"); else - view.set (row, 2, "RW"); + view.set(row, 2, "RW"); - if (command.second->displays_id ()) - view.set (row, 3, "ID"); + if (command.second->displays_id()) view.set(row, 3, "ID"); - if (command.second->needs_gc ()) - view.set (row, 4, "GC"); + if (command.second->needs_gc()) view.set(row, 4, "GC"); - if (command.second->uses_context ()) - view.set (row, 5, "Ctxt"); + if (command.second->uses_context()) view.set(row, 5, "Ctxt"); - if (command.second->accepts_filter ()) - view.set (row, 6, "Filt"); + if (command.second->accepts_filter()) view.set(row, 6, "Filt"); - if (command.second->accepts_modifications ()) - view.set (row, 7, "Mods"); + if (command.second->accepts_modifications()) view.set(row, 7, "Mods"); - if (command.second->accepts_miscellaneous ()) - view.set (row, 8, "Misc"); + if (command.second->accepts_miscellaneous()) view.set(row, 8, "Misc"); - view.set (row, 9, command.second->description ()); + view.set(row, 9, command.second->description()); } - output = optionalBlankLine () - + view.render () - + optionalBlankLine () - + '\n'; + output = optionalBlankLine() + view.render() + optionalBlankLine() + '\n'; return 0; } //////////////////////////////////////////////////////////////////////////////// -CmdCompletionCommands::CmdCompletionCommands () -{ - _keyword = "_commands"; - _usage = "task _commands"; - _description = "Generates a list of all commands, for autocompletion purposes"; - _read_only = true; - _displays_id = false; - _needs_gc = false; - _uses_context = false; - _accepts_filter = false; +CmdCompletionCommands::CmdCompletionCommands() { + _keyword = "_commands"; + _usage = "task _commands"; + _description = "Generates a list of all commands, for autocompletion purposes"; + _read_only = true; + _displays_id = false; + _needs_gc = false; + _uses_context = false; + _accepts_filter = false; _accepts_modifications = false; _accepts_miscellaneous = false; - _category = Command::Category::internal; + _category = Command::Category::internal; } //////////////////////////////////////////////////////////////////////////////// -int CmdCompletionCommands::execute (std::string& output) -{ +int CmdCompletionCommands::execute(std::string& output) { // Get a list of all commands. - std::vector commands; - for (const auto& command : Context::getContext ().commands) - commands.push_back (command.first); + std::vector commands; + for (const auto& command : Context::getContext().commands) commands.push_back(command.first); // Sort alphabetically. - std::sort (commands.begin (), commands.end ()); + std::sort(commands.begin(), commands.end()); std::stringstream out; - for (const auto& c : commands) - out << c << '\n'; + for (const auto& c : commands) out << c << '\n'; - output = out.str (); + output = out.str(); return 0; } //////////////////////////////////////////////////////////////////////////////// -CmdZshCommands::CmdZshCommands () -{ - _keyword = "_zshcommands"; - _usage = "task _zshcommands"; - _description = "Generates a list of all commands, for zsh autocompletion purposes"; - _read_only = true; - _displays_id = false; - _needs_gc = false; - _uses_context = false; - _accepts_filter = false; +CmdZshCommands::CmdZshCommands() { + _keyword = "_zshcommands"; + _usage = "task _zshcommands"; + _description = "Generates a list of all commands, for zsh autocompletion purposes"; + _read_only = true; + _displays_id = false; + _needs_gc = false; + _uses_context = false; + _accepts_filter = false; _accepts_modifications = false; _accepts_miscellaneous = false; - _category = Command::Category::internal; + _category = Command::Category::internal; } //////////////////////////////////////////////////////////////////////////////// -struct ZshCommand -{ - bool operator< (const struct ZshCommand&) const; +struct ZshCommand { + bool operator<(const struct ZshCommand&) const; Command::Category _category; std::string _command; @@ -174,49 +157,40 @@ struct ZshCommand }; //////////////////////////////////////////////////////////////////////////////// -bool ZshCommand::operator< (const struct ZshCommand& other) const -{ +bool ZshCommand::operator<(const struct ZshCommand& other) const { // Lexicographical comparison. - if (_category != other._category) - return (_category < other._category); + if (_category != other._category) return (_category < other._category); - if (_command != other._command) - return (_command < other._command); + if (_command != other._command) return (_command < other._command); - if (_description != other._description) - return (_description < other._description); + if (_description != other._description) return (_description < other._description); return false; } //////////////////////////////////////////////////////////////////////////////// -int CmdZshCommands::execute (std::string& output) -{ +int CmdZshCommands::execute(std::string& output) { // Get a list of all command descriptions, sorted by category and then // alphabetically by command name. // Since not all supported compilers support tuples, we use a least common // denominator alternative: a custom struct type. - std::vector commands; - for (auto& command : Context::getContext ().commands) - { - ZshCommand zshCommand {command.second->category (), - command.first, - command.second->description ()}; - commands.push_back (zshCommand); + std::vector commands; + for (auto& command : Context::getContext().commands) { + ZshCommand zshCommand{command.second->category(), command.first, command.second->description()}; + commands.push_back(zshCommand); } - std::sort (commands.begin (), commands.end ()); + std::sort(commands.begin(), commands.end()); // Emit the commands in order. std::stringstream out; for (const auto& zc : commands) - out << zc._command << ':' - << Command::categoryNames.at (zc._category) << ':' - << zc._description << '\n'; + out << zc._command << ':' << Command::categoryNames.at(zc._category) << ':' << zc._description + << '\n'; - output = out.str (); + output = out.str(); return 0; } diff --git a/src/commands/CmdCommands.h b/src/commands/CmdCommands.h index eb6e45000..59c936717 100644 --- a/src/commands/CmdCommands.h +++ b/src/commands/CmdCommands.h @@ -27,28 +27,26 @@ #ifndef INCLUDED_CMDCOMMANDS #define INCLUDED_CMDCOMMANDS -#include #include -class CmdCommands : public Command -{ -public: - CmdCommands (); - int execute (std::string&); +#include + +class CmdCommands : public Command { + public: + CmdCommands(); + int execute(std::string&); }; -class CmdCompletionCommands : public Command -{ -public: - CmdCompletionCommands (); - int execute (std::string&); +class CmdCompletionCommands : public Command { + public: + CmdCompletionCommands(); + int execute(std::string&); }; -class CmdZshCommands : public Command -{ -public: - CmdZshCommands (); - int execute (std::string&); +class CmdZshCommands : public Command { + public: + CmdZshCommands(); + int execute(std::string&); }; #endif diff --git a/src/commands/CmdConfig.cpp b/src/commands/CmdConfig.cpp index cc845948e..fab9b7631 100644 --- a/src/commands/CmdConfig.cpp +++ b/src/commands/CmdConfig.cpp @@ -28,63 +28,57 @@ // cmake.h include header must come first #include -#include -#include #include #include -#include #include +#include + +#include +#include //////////////////////////////////////////////////////////////////////////////// -CmdConfig::CmdConfig () -{ - _keyword = "config"; - _usage = "task config [name [value | '']]"; - _description = "Change settings in the task configuration"; - _read_only = true; - _displays_id = false; - _needs_gc = false; - _uses_context = false; - _accepts_filter = false; +CmdConfig::CmdConfig() { + _keyword = "config"; + _usage = "task config [name [value | '']]"; + _description = "Change settings in the task configuration"; + _read_only = true; + _displays_id = false; + _needs_gc = false; + _uses_context = false; + _accepts_filter = false; _accepts_modifications = false; _accepts_miscellaneous = true; - _category = Command::Category::config; + _category = Command::Category::config; } //////////////////////////////////////////////////////////////////////////////// -bool CmdConfig::setConfigVariable ( - const std::string& name, - const std::string& value, - bool confirmation /* = false */) -{ +bool CmdConfig::setConfigVariable(const std::string& name, const std::string& value, + bool confirmation /* = false */) { // Read .taskrc (or equivalent) - std::vector contents; - File::read (Context::getContext ().config.file (), contents); + std::vector contents; + File::read(Context::getContext().config.file(), contents); auto found = false; auto change = false; - for (auto& line : contents) - { + for (auto& line : contents) { // Get l-trimmed version of the line - auto trimmed_line = trim (line, " "); + auto trimmed_line = trim(line, " "); // If there is a comment on the line, it must follow the pattern. - auto comment = line.find ('#'); - auto pos = trimmed_line.find (name + '='); + auto comment = line.find('#'); + auto pos = trimmed_line.find(name + '='); // TODO: Use std::regex here - if (pos == 0) - { + if (pos == 0) { found = true; if (!confirmation || - confirm (format ("Are you sure you want to change the value of '{1}' from '{2}' to '{3}'?", name, Context::getContext ().config.get (name), value))) - { - auto new_line = line.substr (0, pos + name.length () + 1) + json::encode (value); + confirm(format("Are you sure you want to change the value of '{1}' from '{2}' to '{3}'?", + name, Context::getContext().config.get(name), value))) { + auto new_line = line.substr(0, pos + name.length() + 1) + json::encode(value); // Preserve the comment - if (comment != std::string::npos) - new_line += " " + line.substr (comment); + if (comment != std::string::npos) new_line += " " + line.substr(comment); // Rewrite the line line = new_line; @@ -94,61 +88,52 @@ bool CmdConfig::setConfigVariable ( } // Not found, so append instead. - if (! found && - (! confirmation || - confirm (format ("Are you sure you want to add '{1}' with a value of '{2}'?", name, value)))) - { - contents.push_back (name + '=' + json::encode (value)); + if (!found && + (!confirmation || + confirm(format("Are you sure you want to add '{1}' with a value of '{2}'?", name, value)))) { + contents.push_back(name + '=' + json::encode(value)); change = true; } - if (change) - File::write (Context::getContext ().config.file (), contents); + if (change) File::write(Context::getContext().config.file(), contents); return change; } //////////////////////////////////////////////////////////////////////////////// -int CmdConfig::unsetConfigVariable (const std::string& name, bool confirmation /* = false */) -{ +int CmdConfig::unsetConfigVariable(const std::string& name, bool confirmation /* = false */) { // Read .taskrc (or equivalent) - std::vector contents; - File::read (Context::getContext ().config.file (), contents); + std::vector contents; + File::read(Context::getContext().config.file(), contents); auto found = false; auto change = false; - for (auto line = contents.begin (); line != contents.end (); ) - { + for (auto line = contents.begin(); line != contents.end();) { auto lineDeleted = false; // Get l-trimmed version of the line // If there is a comment on the line, it must follow the pattern. - auto pos = trim (*line, " ").find (name + '='); + auto pos = trim(*line, " ").find(name + '='); // TODO: Use std::regex here - if (pos == 0) - { + if (pos == 0) { found = true; // Remove name - if (!confirmation || - confirm (format ("Are you sure you want to remove '{1}'?", name))) - { + if (!confirmation || confirm(format("Are you sure you want to remove '{1}'?", name))) { // vector::erase method returns a valid iterator to the next object - line = contents.erase (line); + line = contents.erase(line); lineDeleted = true; change = true; } } - if (! lineDeleted) - line++; + if (!lineDeleted) line++; } - if (change) - File::write (Context::getContext ().config.file (), contents); + if (change) File::write(Context::getContext().config.file(), contents); if (change && found) return 0; @@ -159,107 +144,88 @@ int CmdConfig::unsetConfigVariable (const std::string& name, bool confirmation / } //////////////////////////////////////////////////////////////////////////////// -int CmdConfig::execute (std::string& output) -{ +int CmdConfig::execute(std::string& output) { auto rc = 0; std::stringstream out; // Get the non-attribute, non-fancy command line arguments. - std::vector words = Context::getContext ().cli2.getWords (); + std::vector words = Context::getContext().cli2.getWords(); // Support: // task config name value # set name to value // task config name "" # set name to blank // task config name # remove name - if (words.size ()) - { - auto confirmation = Context::getContext ().config.getBoolean ("confirmation"); + if (words.size()) { + auto confirmation = Context::getContext().config.getBoolean("confirmation"); auto found = false; auto name = words[0]; std::string value = ""; // Join the remaining words into config variable's value - if (words.size () > 1) - { - for (unsigned int i = 1; i < words.size (); ++i) - { - if (i > 1) - value += ' '; + if (words.size() > 1) { + for (unsigned int i = 1; i < words.size(); ++i) { + if (i > 1) value += ' '; value += words[i]; } } - if (name != "") - { + if (name != "") { auto change = false; // task config name value // task config name "" - if (words.size () > 1) - change = setConfigVariable(name, value, confirmation); + if (words.size() > 1) change = setConfigVariable(name, value, confirmation); // task config name - else - { + else { rc = unsetConfigVariable(name, confirmation); - if (rc == 0) - { + if (rc == 0) { change = true; found = true; - } - else if (rc == 1) + } else if (rc == 1) found = true; - if (! found) - throw format ("No entry named '{1}' found.", name); + if (!found) throw format("No entry named '{1}' found.", name); } // Show feedback depending on whether .taskrc has been rewritten - if (change) - { - out << format ("Config file {1} modified.", Context::getContext ().config.file ()) - << '\n'; - } - else + if (change) { + out << format("Config file {1} modified.", Context::getContext().config.file()) << '\n'; + } else out << "No changes made.\n"; - } - else - throw std::string ("Specify the name of a config variable to modify."); + } else + throw std::string("Specify the name of a config variable to modify."); - output = out.str (); - } - else - throw std::string ("Specify the name of a config variable to modify."); + output = out.str(); + } else + throw std::string("Specify the name of a config variable to modify."); return rc; } //////////////////////////////////////////////////////////////////////////////// -CmdCompletionConfig::CmdCompletionConfig () -{ - _keyword = "_config"; - _usage = "task _config"; - _description = "Lists all supported configuration variables, for completion purposes"; - _read_only = true; - _displays_id = false; - _needs_gc = false; - _uses_context = false; - _accepts_filter = false; +CmdCompletionConfig::CmdCompletionConfig() { + _keyword = "_config"; + _usage = "task _config"; + _description = "Lists all supported configuration variables, for completion purposes"; + _read_only = true; + _displays_id = false; + _needs_gc = false; + _uses_context = false; + _accepts_filter = false; _accepts_modifications = false; _accepts_miscellaneous = false; - _category = Command::Category::internal; + _category = Command::Category::internal; } //////////////////////////////////////////////////////////////////////////////// -int CmdCompletionConfig::execute (std::string& output) -{ - auto configs = Context::getContext ().config.all (); - std::sort (configs.begin (), configs.end ()); +int CmdCompletionConfig::execute(std::string& output) { + auto configs = Context::getContext().config.all(); + std::sort(configs.begin(), configs.end()); - for (const auto& config : configs) - output += config + '\n'; + for (const auto& config : configs) output += config + '\n'; return 0; } diff --git a/src/commands/CmdConfig.h b/src/commands/CmdConfig.h index 4cf6c9583..866c83385 100644 --- a/src/commands/CmdConfig.h +++ b/src/commands/CmdConfig.h @@ -27,23 +27,22 @@ #ifndef INCLUDED_CMDCONFIG #define INCLUDED_CMDCONFIG -#include #include -class CmdConfig : public Command -{ -public: - CmdConfig (); - static bool setConfigVariable (const std::string&, const std::string&, bool confirmation = false); - static int unsetConfigVariable (const std::string&, bool confirmation = false); - int execute (std::string&); +#include + +class CmdConfig : public Command { + public: + CmdConfig(); + static bool setConfigVariable(const std::string&, const std::string&, bool confirmation = false); + static int unsetConfigVariable(const std::string&, bool confirmation = false); + int execute(std::string&); }; -class CmdCompletionConfig : public Command -{ -public: - CmdCompletionConfig (); - int execute (std::string&); +class CmdCompletionConfig : public Command { + public: + CmdCompletionConfig(); + int execute(std::string&); }; #endif diff --git a/src/commands/CmdContext.cpp b/src/commands/CmdContext.cpp index b010b62f9..adcff94c7 100644 --- a/src/commands/CmdContext.cpp +++ b/src/commands/CmdContext.cpp @@ -27,60 +27,62 @@ #include // cmake.h include header must come first -#include #include -#include +#include #include #include -#include -#include -#include +#include #include #include #include #include +#include +#include +#include + //////////////////////////////////////////////////////////////////////////////// -CmdContext::CmdContext () -{ - _keyword = "context"; - _usage = "task context [ | ]"; - _description = "Set and define contexts (default filters / modifications)"; - _read_only = true; - _displays_id = false; - _needs_gc = false; - _uses_context = false; - _accepts_filter = false; +CmdContext::CmdContext() { + _keyword = "context"; + _usage = "task context [ | ]"; + _description = "Set and define contexts (default filters / modifications)"; + _read_only = true; + _displays_id = false; + _needs_gc = false; + _uses_context = false; + _accepts_filter = false; _accepts_modifications = false; _accepts_miscellaneous = true; - _category = Command::Category::context; + _category = Command::Category::context; } //////////////////////////////////////////////////////////////////////////////// -int CmdContext::execute (std::string& output) -{ +int CmdContext::execute(std::string& output) { std::stringstream out; // Get the non-attribute, non-fancy command line arguments. - auto words = Context::getContext ().cli2.getWords (); - if (words.size () > 0) - { + auto words = Context::getContext().cli2.getWords(); + if (words.size() > 0) { auto subcommand = words[0]; - if (subcommand == "define") defineContext (words, out); - else if (subcommand == "delete") deleteContext (words, out); - else if (subcommand == "list") listContexts (out); - else if (subcommand == "none") unsetContext (out); - else if (subcommand == "show") showContext (out); - else if (words.size ()) setContext (words, out); - } - else - { - listContexts (out); + if (subcommand == "define") + defineContext(words, out); + else if (subcommand == "delete") + deleteContext(words, out); + else if (subcommand == "list") + listContexts(out); + else if (subcommand == "none") + unsetContext(out); + else if (subcommand == "show") + showContext(out); + else if (words.size()) + setContext(words, out); + } else { + listContexts(out); out << "Use 'task context none' to unset the current context.\n"; } - output = out.str (); + output = out.str(); return 0; } @@ -90,17 +92,14 @@ int CmdContext::execute (std::string& output) // // If to is specified as 0 (default value), all the remaining words will be joined. // -std::string CmdContext::joinWords (const std::vector & words, unsigned int from, unsigned int to /* = 0 */) -{ +std::string CmdContext::joinWords(const std::vector& words, unsigned int from, + unsigned int to /* = 0 */) { std::string value = ""; - if (to == 0) - to = words.size(); + if (to == 0) to = words.size(); - for (unsigned int i = from; i < to; ++i) - { - if (i > from) - value += ' '; + for (unsigned int i = from; i < to; ++i) { + if (i > from) value += ' '; value += words[i]; } @@ -119,33 +118,28 @@ std::string CmdContext::joinWords (const std::vector & words, unsig // invalid due to a wrong modifier use, the modifier string will contain the // first invalid modifier. // -bool CmdContext::validateWriteContext (const std::vector & lexedArgs, std::string& reason) -{ - for (auto &arg: lexedArgs) { +bool CmdContext::validateWriteContext(const std::vector& lexedArgs, std::string& reason) { + for (auto& arg : lexedArgs) { if (arg._lextype == Lexer::Type::op) - if (arg.attribute ("raw") == "or") - { + if (arg.attribute("raw") == "or") { reason = "contains the 'OR' operator"; return false; } if (arg._lextype == Lexer::Type::pair) { - auto modifier = arg.attribute ("modifier"); - if (modifier != "" && modifier != "is" && modifier != "equals") - { - reason = format ("contains an attribute modifier '{1}'", arg.attribute ("raw")); + auto modifier = arg.attribute("modifier"); + if (modifier != "" && modifier != "is" && modifier != "equals") { + reason = format("contains an attribute modifier '{1}'", arg.attribute("raw")); return false; } } if (arg._lextype == Lexer::Type::tag) { - if (arg.attribute ("sign") == "-") - { - reason = format ("contains tag exclusion '{1}'", arg.attribute ("raw")); + if (arg.attribute("sign") == "-") { + reason = format("contains tag exclusion '{1}'", arg.attribute("raw")); return false; } } - } return true; @@ -154,22 +148,20 @@ bool CmdContext::validateWriteContext (const std::vector & lexedArgs, std::s //////////////////////////////////////////////////////////////////////////////// // Returns all user defined contexts. // -std::vector CmdContext::getContexts () -{ - std::set contexts; +std::vector CmdContext::getContexts() { + std::set contexts; - for (auto& name : Context::getContext ().config) - if (name.first.substr (0, 8) == "context.") - { - std::string suffix = name.first.substr (8); + for (auto& name : Context::getContext().config) + if (name.first.substr(0, 8) == "context.") { + std::string suffix = name.first.substr(8); - if (suffix.find (".") != std::string::npos) - contexts.insert (suffix.substr (0, suffix.find ("."))); + if (suffix.find(".") != std::string::npos) + contexts.insert(suffix.substr(0, suffix.find("."))); else - contexts.insert (suffix); + contexts.insert(suffix); } - return std::vector (contexts.begin (), contexts.end ()); + return std::vector(contexts.begin(), contexts.end()); } //////////////////////////////////////////////////////////////////////////////// @@ -182,85 +174,85 @@ std::vector CmdContext::getContexts () // Invoked with: task context define // Example: task context define home project:Home // -void CmdContext::defineContext (const std::vector & words, std::stringstream& out) -{ - auto config = Context::getContext ().config; - bool confirmation = config.getBoolean ("confirmation"); +void CmdContext::defineContext(const std::vector& words, std::stringstream& out) { + auto config = Context::getContext().config; + bool confirmation = config.getBoolean("confirmation"); - if (words.size () > 2) - { + if (words.size() > 2) { auto name = "context." + words[1]; - auto value = joinWords (words, 2); + auto value = joinWords(words, 2); // Make sure nobody creates a context with name 'list', 'none' or 'show' - if (words[1] == "none" or words[1] == "list" or words[1] == "show") - { - throw format ("The name '{1}' is reserved and not allowed to use as a context name.", words[1]); + if (words[1] == "none" or words[1] == "list" or words[1] == "show") { + throw format("The name '{1}' is reserved and not allowed to use as a context name.", + words[1]); } // Extract MISCELLANEOUS arguments (containing the filter definition) for later analysis - std::vector lexedArgs = Context::getContext ().cli2.getMiscellaneous(); + std::vector lexedArgs = Context::getContext().cli2.getMiscellaneous(); // Check if the value is a proper filter by filtering current pending.data Filter filter; - std::vector filtered; - auto pending = Context::getContext ().tdb2.pending_tasks (); + std::vector filtered; + auto pending = Context::getContext().tdb2.pending_tasks(); - try - { + try { // This result is not used, and is just to check validity. - Context::getContext ().cli2.addFilter (value); - filter.subset (pending, filtered); - } - catch (std::string exception) - { - throw format ("Filter validation failed: {1}", exception); + Context::getContext().cli2.addFilter(value); + filter.subset(pending, filtered); + } catch (std::string exception) { + throw format("Filter validation failed: {1}", exception); } // Make user explicitly confirm filters that are matching no pending tasks - if (filtered.size () == 0) + if (filtered.size() == 0) if (confirmation && - ! confirm (format ("The filter '{1}' matches 0 pending tasks. Do you wish to continue?", value))) - throw std::string ("Context definition aborted."); + !confirm( + format("The filter '{1}' matches 0 pending tasks. Do you wish to continue?", value))) + throw std::string("Context definition aborted."); std::string reason = ""; - bool valid_write_context = CmdContext::validateWriteContext (lexedArgs, reason); + bool valid_write_context = CmdContext::validateWriteContext(lexedArgs, reason); - if (! valid_write_context) - { + if (!valid_write_context) { std::stringstream warning; - warning << format ("The filter '{1}' is not a valid modification string, because it contains {2}.", value, reason) - << "\nAs such, value for the write context cannot be set (context will not apply on task add / task log).\n\n" - << format ("Please use 'task config context.{1}.write ' to set default attribute values for new tasks in this context manually.\n\n", words[1]); - out << colorizeFootnote (warning.str ()); + warning + << format("The filter '{1}' is not a valid modification string, because it contains {2}.", + value, reason) + << "\nAs such, value for the write context cannot be set (context will not apply on task " + "add / task log).\n\n" + << format( + "Please use 'task config context.{1}.write ' to set default " + "attribute values for new tasks in this context manually.\n\n", + words[1]); + out << colorizeFootnote(warning.str()); } // Set context definition config variable - bool read_success = CmdConfig::setConfigVariable (name + ".read", value, confirmation); + bool read_success = CmdConfig::setConfigVariable(name + ".read", value, confirmation); bool write_success = false; if (valid_write_context) - write_success = CmdConfig::setConfigVariable (name + ".write", value, confirmation); + write_success = CmdConfig::setConfigVariable(name + ".write", value, confirmation); // Remove old-school context name, if it exists, assuming the read context was defined if (read_success) - if (config.has (name)) { - CmdConfig::unsetConfigVariable (name, false); + if (config.has(name)) { + CmdConfig::unsetConfigVariable(name, false); } if (!read_success and !write_success) - throw format ("Context '{1}' not defined.", words[1]); + throw format("Context '{1}' not defined.", words[1]); else if (!read_success) - out << format ("Context '{1}' defined (write only).", words[1]); + out << format("Context '{1}' defined (write only).", words[1]); else if (!write_success) - out << format ("Context '{1}' defined (read only).", words[1]); + out << format("Context '{1}' defined (read only).", words[1]); else - out << format ("Context '{1}' defined (read, write).", words[1]); + out << format("Context '{1}' defined (read, write).", words[1]); - out << format (" Use 'task context {1}' to activate.\n", words[1]); - } - else - throw std::string ("Both context name and its definition must be provided."); + out << format(" Use 'task context {1}' to activate.\n", words[1]); + } else + throw std::string("Both context name and its definition must be provided."); } //////////////////////////////////////////////////////////////////////////////// @@ -273,36 +265,33 @@ void CmdContext::defineContext (const std::vector & words, std::str // Invoked with: task context delete // Example: task context delete home // -void CmdContext::deleteContext (const std::vector & words, std::stringstream& out) -{ - if (words.size () > 1) - { +void CmdContext::deleteContext(const std::vector& words, std::stringstream& out) { + if (words.size() > 1) { // Delete the specified context auto name = "context." + words[1]; - auto confirmation = Context::getContext ().config.getBoolean ("confirmation"); - if (confirmation && ! confirm (format ("Do you want to delete context '{1}'?", words[1]))) - throw format ("Context '{1}' not deleted.", words[1]); + auto confirmation = Context::getContext().config.getBoolean("confirmation"); + if (confirmation && !confirm(format("Do you want to delete context '{1}'?", words[1]))) + throw format("Context '{1}' not deleted.", words[1]); // Delete legacy format and .read / .write flavours auto rc = CmdConfig::unsetConfigVariable(name, false); - rc += CmdConfig::unsetConfigVariable(name + ".read", false); - rc += CmdConfig::unsetConfigVariable(name + ".write", false); + rc += CmdConfig::unsetConfigVariable(name + ".read", false); + rc += CmdConfig::unsetConfigVariable(name + ".write", false); // If the currently set context was deleted, unset it - if (Context::getContext ().config.get ("context") == words[1]) + if (Context::getContext().config.get("context") == words[1]) CmdConfig::unsetConfigVariable("context", false); // Output feedback, rc should be even because only 0 (found and removed) // and 2 (not found) are aceptable return values from unsetConfigVariable if (rc % 2 != 0) - throw format ("Context '{1}' not deleted.", words[1]); + throw format("Context '{1}' not deleted.", words[1]); else if (rc == 6) - throw format ("Context '{1}' not found.", words[1]); + throw format("Context '{1}' not found.", words[1]); - out << format ("Context '{1}' deleted.\n", words[1]); - } - else + out << format("Context '{1}' deleted.\n", words[1]); + } else throw std::string("Context name needs to be specified."); } @@ -314,48 +303,41 @@ void CmdContext::deleteContext (const std::vector & words, std::str // Invoked with: task context list // Example: task context list // -void CmdContext::listContexts (std::stringstream& out) -{ +void CmdContext::listContexts(std::stringstream& out) { auto contexts = getContexts(); - if (contexts.size ()) - { - std::sort (contexts.begin (), contexts.end ()); + if (contexts.size()) { + std::sort(contexts.begin(), contexts.end()); Table table; - table.width (Context::getContext ().getWidth ()); - table.add ("Name"); - table.add ("Type"); - table.add ("Definition"); - table.add ("Active"); - setHeaderUnderline (table); + table.width(Context::getContext().getWidth()); + table.add("Name"); + table.add("Type"); + table.add("Definition"); + table.add("Active"); + setHeaderUnderline(table); - std::string activeContext = Context::getContext ().config.get ("context"); + std::string activeContext = Context::getContext().config.get("context"); - for (auto& userContext : contexts) - { + for (auto& userContext : contexts) { std::string active = "no"; - if (userContext == activeContext) - active = "yes"; + if (userContext == activeContext) active = "yes"; - int row = table.addRow (); - table.set (row, 0, userContext); - table.set (row, 1, "read"); - table.set (row, 2, Context::getContext ().getTaskContext("read", userContext)); - table.set (row, 3, active); + int row = table.addRow(); + table.set(row, 0, userContext); + table.set(row, 1, "read"); + table.set(row, 2, Context::getContext().getTaskContext("read", userContext)); + table.set(row, 3, active); - row = table.addRow (); - table.set (row, 0, ""); - table.set (row, 1, "write"); - table.set (row, 2, Context::getContext ().getTaskContext("write", userContext)); - table.set (row, 3, active); + row = table.addRow(); + table.set(row, 0, ""); + table.set(row, 1, "write"); + table.set(row, 2, Context::getContext().getTaskContext("write", userContext)); + table.set(row, 3, active); } - out << optionalBlankLine () - << table.render () - << optionalBlankLine (); - } - else - throw std::string ("No contexts defined."); + out << optionalBlankLine() << table.render() << optionalBlankLine(); + } else + throw std::string("No contexts defined."); } //////////////////////////////////////////////////////////////////////////////// @@ -369,23 +351,21 @@ void CmdContext::listContexts (std::stringstream& out) // Invoked with: task context // Example: task context home // -void CmdContext::setContext (const std::vector & words, std::stringstream& out) -{ +void CmdContext::setContext(const std::vector& words, std::stringstream& out) { auto value = words[0]; - auto contexts = getContexts (); + auto contexts = getContexts(); // Check that the specified context is defined - if (std::find (contexts.begin (), contexts.end (), value) == contexts.end ()) - throw format ("Context '{1}' not found.", value); + if (std::find(contexts.begin(), contexts.end(), value) == contexts.end()) + throw format("Context '{1}' not found.", value); // Set the active context. // Should always succeed, as we do not require confirmation. - bool success = CmdConfig::setConfigVariable ("context", value, false); + bool success = CmdConfig::setConfigVariable("context", value, false); - if (! success) - throw format ("Context '{1}' not applied.", value); + if (!success) throw format("Context '{1}' not applied.", value); - out << format ("Context '{1}' set. Use 'task context none' to remove.\n", value); + out << format("Context '{1}' set. Use 'task context none' to remove.\n", value); } //////////////////////////////////////////////////////////////////////////////// @@ -396,20 +376,17 @@ void CmdContext::setContext (const std::vector & words, std::string // Invoked with: task context show // Example: task context show // -void CmdContext::showContext (std::stringstream& out) -{ - auto currentContext = Context::getContext ().config.get ("context"); +void CmdContext::showContext(std::stringstream& out) { + auto currentContext = Context::getContext().config.get("context"); if (currentContext == "") out << "No context is currently applied.\n"; - else - { - out << format ( - "Context '{1}' with \n\n* read filter: '{2}'\n* write filter: '{3}'\n\nis currently applied.\n", - currentContext, - Context::getContext ().getTaskContext("read", ""), - Context::getContext ().getTaskContext("write", "") - ); + else { + out << format( + "Context '{1}' with \n\n* read filter: '{2}'\n* write filter: '{3}'\n\nis currently " + "applied.\n", + currentContext, Context::getContext().getTaskContext("read", ""), + Context::getContext().getTaskContext("write", "")); } } @@ -423,35 +400,30 @@ void CmdContext::showContext (std::stringstream& out) // Invoked with: task context none // Example: task context none // -void CmdContext::unsetContext (std::stringstream& out) -{ - if (CmdConfig::unsetConfigVariable ("context", false)) - throw std::string ("Context not unset."); +void CmdContext::unsetContext(std::stringstream& out) { + if (CmdConfig::unsetConfigVariable("context", false)) throw std::string("Context not unset."); out << "Context unset.\n"; } //////////////////////////////////////////////////////////////////////////////// -CmdCompletionContext::CmdCompletionContext () -{ - _keyword = "_context"; - _usage = "task _context"; - _description = "Lists all supported contexts, for completion purposes"; - _read_only = true; - _displays_id = false; - _needs_gc = false; - _uses_context = false; - _accepts_filter = false; +CmdCompletionContext::CmdCompletionContext() { + _keyword = "_context"; + _usage = "task _context"; + _description = "Lists all supported contexts, for completion purposes"; + _read_only = true; + _displays_id = false; + _needs_gc = false; + _uses_context = false; + _accepts_filter = false; _accepts_modifications = false; _accepts_miscellaneous = false; - _category = Command::Category::internal; + _category = Command::Category::internal; } //////////////////////////////////////////////////////////////////////////////// -int CmdCompletionContext::execute (std::string& output) -{ - for (auto& context : CmdContext::getContexts ()) - output += context + '\n'; +int CmdCompletionContext::execute(std::string& output) { + for (auto& context : CmdContext::getContexts()) output += context + '\n'; return 0; } diff --git a/src/commands/CmdContext.h b/src/commands/CmdContext.h index c21e8a0b3..a14197ccb 100644 --- a/src/commands/CmdContext.h +++ b/src/commands/CmdContext.h @@ -27,31 +27,30 @@ #ifndef INCLUDED_CMDCONTEXT #define INCLUDED_CMDCONTEXT -#include -#include #include +#include -class CmdContext : public Command -{ -public: - CmdContext (); - int execute (std::string&); - std::string joinWords (const std::vector &, unsigned int, unsigned int = 0); - bool validateWriteContext (const std::vector &, std::string&); - static std::vector getContexts (); - void defineContext (const std::vector &, std::stringstream&); - void deleteContext (const std::vector &, std::stringstream&); - void listContexts (std::stringstream&); - void setContext (const std::vector &, std::stringstream&); - void showContext (std::stringstream&); - void unsetContext (std::stringstream&); +#include + +class CmdContext : public Command { + public: + CmdContext(); + int execute(std::string&); + std::string joinWords(const std::vector&, unsigned int, unsigned int = 0); + bool validateWriteContext(const std::vector&, std::string&); + static std::vector getContexts(); + void defineContext(const std::vector&, std::stringstream&); + void deleteContext(const std::vector&, std::stringstream&); + void listContexts(std::stringstream&); + void setContext(const std::vector&, std::stringstream&); + void showContext(std::stringstream&); + void unsetContext(std::stringstream&); }; -class CmdCompletionContext : public Command -{ -public: - CmdCompletionContext (); - int execute (std::string&); +class CmdCompletionContext : public Command { + public: + CmdCompletionContext(); + int execute(std::string&); }; #endif diff --git a/src/commands/CmdCount.cpp b/src/commands/CmdCount.cpp index f577136ba..0da28bc1b 100644 --- a/src/commands/CmdCount.cpp +++ b/src/commands/CmdCount.cpp @@ -29,38 +29,37 @@ #include #include -#include #include +#include //////////////////////////////////////////////////////////////////////////////// -CmdCount::CmdCount () -{ - _keyword = "count"; - _usage = "task count"; - _description = "Counts matching tasks"; - _read_only = true; - _displays_id = false; - _needs_gc = true; - _uses_context = true; - _accepts_filter = true; +CmdCount::CmdCount() { + _keyword = "count"; + _usage = "task count"; + _description = "Counts matching tasks"; + _read_only = true; + _displays_id = false; + _needs_gc = true; + _uses_context = true; + _accepts_filter = true; _accepts_modifications = false; _accepts_miscellaneous = false; - _category = Command::Category::metadata; + _category = Command::Category::metadata; } //////////////////////////////////////////////////////////////////////////////// -int CmdCount::execute (std::string& output) -{ +int CmdCount::execute(std::string& output) { // Apply filter. - handleUntil (); - handleRecurrence (); + handleUntil(); + handleRecurrence(); Filter filter; - std::vector filtered; - filter.subset (filtered); + std::vector filtered; + filter.subset(filtered); // Find number of matching tasks. Skip recurring parent tasks. - int count = std::count_if(filtered.begin(), filtered.end(), [](const auto& task){ return task.getStatus () != Task::recurring; }); - output = format (count) + '\n'; + int count = std::count_if(filtered.begin(), filtered.end(), + [](const auto& task) { return task.getStatus() != Task::recurring; }); + output = format(count) + '\n'; return 0; } diff --git a/src/commands/CmdCount.h b/src/commands/CmdCount.h index bea9f6851..a7d49cfb8 100644 --- a/src/commands/CmdCount.h +++ b/src/commands/CmdCount.h @@ -27,14 +27,14 @@ #ifndef INCLUDED_CMDCOUNT #define INCLUDED_CMDCOUNT -#include #include -class CmdCount : public Command -{ -public: - CmdCount (); - int execute (std::string&); +#include + +class CmdCount : public Command { + public: + CmdCount(); + int execute(std::string&); }; #endif diff --git a/src/commands/CmdCustom.cpp b/src/commands/CmdCustom.cpp index 7266b2187..0537f265d 100644 --- a/src/commands/CmdCustom.cpp +++ b/src/commands/CmdCustom.cpp @@ -28,178 +28,157 @@ // cmake.h include header must come first #include -#include -#include -#include -#include -#include -#include #include #include #include #include #include #include -#include -#include #include +#include +#include +#include + +#include +#include +#include +#include +#include //////////////////////////////////////////////////////////////////////////////// -CmdCustom::CmdCustom ( - const std::string& keyword, - const std::string& usage, - const std::string& description) -{ - _keyword = keyword; - _usage = usage; - _description = description; - _read_only = true; - _displays_id = true; - _needs_gc = true; - _uses_context = true; - _accepts_filter = true; +CmdCustom::CmdCustom(const std::string& keyword, const std::string& usage, + const std::string& description) { + _keyword = keyword; + _usage = usage; + _description = description; + _read_only = true; + _displays_id = true; + _needs_gc = true; + _uses_context = true; + _accepts_filter = true; _accepts_modifications = false; _accepts_miscellaneous = false; - _category = Category::report; + _category = Category::report; } //////////////////////////////////////////////////////////////////////////////// // Whether a report uses context is defined by the report..context // configuration variable. // -bool CmdCustom::uses_context () const -{ - auto config = Context::getContext ().config; +bool CmdCustom::uses_context() const { + auto config = Context::getContext().config; auto key = "report." + _keyword + ".context"; - if (config.has (key)) - return config.getBoolean (key); + if (config.has(key)) + return config.getBoolean(key); else return _uses_context; } //////////////////////////////////////////////////////////////////////////////// -int CmdCustom::execute (std::string& output) -{ +int CmdCustom::execute(std::string& output) { auto rc = 0; // Load report configuration. - auto reportColumns = Context::getContext ().config.get ("report." + _keyword + ".columns"); - auto reportLabels = Context::getContext ().config.get ("report." + _keyword + ".labels"); - auto reportSort = Context::getContext ().config.get ("report." + _keyword + ".sort"); - auto reportFilter = Context::getContext ().config.get ("report." + _keyword + ".filter"); + auto reportColumns = Context::getContext().config.get("report." + _keyword + ".columns"); + auto reportLabels = Context::getContext().config.get("report." + _keyword + ".labels"); + auto reportSort = Context::getContext().config.get("report." + _keyword + ".sort"); + auto reportFilter = Context::getContext().config.get("report." + _keyword + ".filter"); - auto columns = split (reportColumns, ','); - validateReportColumns (columns); + auto columns = split(reportColumns, ','); + validateReportColumns(columns); - auto labels = split (reportLabels, ','); + auto labels = split(reportLabels, ','); - if (columns.size () != labels.size () && labels.size () != 0) - throw format ("There are different numbers of columns and labels for report '{1}'.", _keyword); + if (columns.size() != labels.size() && labels.size() != 0) + throw format("There are different numbers of columns and labels for report '{1}'.", _keyword); - auto sortOrder = split (reportSort, ','); - if (sortOrder.size () != 0 && - sortOrder[0] != "none") - validateSortColumns (sortOrder); + auto sortOrder = split(reportSort, ','); + if (sortOrder.size() != 0 && sortOrder[0] != "none") validateSortColumns(sortOrder); // Add the report filter to any existing filter. - if (reportFilter != "") - Context::getContext ().cli2.addFilter (reportFilter); + if (reportFilter != "") Context::getContext().cli2.addFilter(reportFilter); // Make sure reccurent tasks are generated. - handleUntil (); - handleRecurrence (); + handleUntil(); + handleRecurrence(); // Apply filter. Filter filter; - std::vector filtered; - filter.subset (filtered); + std::vector filtered; + filter.subset(filtered); - std::vector sequence; - if (sortOrder.size () && - sortOrder[0] == "none") - { + std::vector sequence; + if (sortOrder.size() && sortOrder[0] == "none") { // Assemble a sequence vector that represents the tasks listed in // Context::getContext ().cli2._uuid_ranges, in the order in which they appear. This // equates to no sorting, just a specified order. - sortOrder.clear (); - for (auto& i : Context::getContext ().cli2._uuid_list) - for (unsigned int t = 0; t < filtered.size (); ++t) - if (filtered[t].get ("uuid") == i) - sequence.push_back (t); - } - else - { + sortOrder.clear(); + for (auto& i : Context::getContext().cli2._uuid_list) + for (unsigned int t = 0; t < filtered.size(); ++t) + if (filtered[t].get("uuid") == i) sequence.push_back(t); + } else { // There is a sortOrder, so sorting will take place, which means the initial // order of sequence is ascending. - for (unsigned int i = 0; i < filtered.size (); ++i) - sequence.push_back (i); + for (unsigned int i = 0; i < filtered.size(); ++i) sequence.push_back(i); // Sort the tasks. - if (sortOrder.size ()) - sort_tasks (filtered, sequence, reportSort); + if (sortOrder.size()) sort_tasks(filtered, sequence, reportSort); } // Configure the view. ViewTask view; - view.width (Context::getContext ().getWidth ()); - view.leftMargin (Context::getContext ().config.getInteger ("indent.report")); - view.extraPadding (Context::getContext ().config.getInteger ("row.padding")); - view.intraPadding (Context::getContext ().config.getInteger ("column.padding")); + view.width(Context::getContext().getWidth()); + view.leftMargin(Context::getContext().config.getInteger("indent.report")); + view.extraPadding(Context::getContext().config.getInteger("row.padding")); + view.intraPadding(Context::getContext().config.getInteger("column.padding")); - if (Context::getContext ().color ()) - { - Color label (Context::getContext ().config.get ("color.label")); - view.colorHeader (label); + if (Context::getContext().color()) { + Color label(Context::getContext().config.get("color.label")); + view.colorHeader(label); - Color label_sort (Context::getContext ().config.get ("color.label.sort")); - view.colorSortHeader (label_sort); + Color label_sort(Context::getContext().config.get("color.label.sort")); + view.colorSortHeader(label_sort); // If an alternating row color is specified, notify the table. - Color alternate (Context::getContext ().config.get ("color.alternate")); - if (alternate.nontrivial ()) - { - view.colorOdd (alternate); - view.intraColorOdd (alternate); + Color alternate(Context::getContext().config.get("color.alternate")); + if (alternate.nontrivial()) { + view.colorOdd(alternate); + view.intraColorOdd(alternate); } } // Capture columns that are sorted. - std::vector sortColumns; + std::vector sortColumns; // Add the break columns, if any. - for (const auto& so : sortOrder) - { + for (const auto& so : sortOrder) { std::string name; bool ascending; bool breakIndicator; - Context::getContext ().decomposeSortField (so, name, ascending, breakIndicator); + Context::getContext().decomposeSortField(so, name, ascending, breakIndicator); - if (breakIndicator) - view.addBreak (name); + if (breakIndicator) view.addBreak(name); - sortColumns.push_back (name); + sortColumns.push_back(name); } // Add the columns and labels. - for (unsigned int i = 0; i < columns.size (); ++i) - { - Column* c = Column::factory (columns[i], _keyword); - if (i < labels.size ()) - c->setLabel (labels[i]); + for (unsigned int i = 0; i < columns.size(); ++i) { + Column* c = Column::factory(columns[i], _keyword); + if (i < labels.size()) c->setLabel(labels[i]); - bool sort = std::find (sortColumns.begin (), sortColumns.end (), c->name ()) != sortColumns.end () - ? true - : false; + bool sort = std::find(sortColumns.begin(), sortColumns.end(), c->name()) != sortColumns.end() + ? true + : false; - view.add (c, sort); + view.add(c, sort); } // How many lines taken up by table header? int table_header = 0; - if (Context::getContext ().verbose ("label")) - { - if (Context::getContext ().color () && Context::getContext ().config.getBoolean ("fontunderline")) + if (Context::getContext().verbose("label")) { + if (Context::getContext().color() && Context::getContext().config.getBoolean("fontunderline")) table_header = 1; // Underlining doesn't use extra line. else table_header = 2; // Dashes use an extra line. @@ -208,92 +187,77 @@ int CmdCustom::execute (std::string& output) // Report output can be limited by rows or lines. auto maxrows = 0; auto maxlines = 0; - Context::getContext ().getLimits (maxrows, maxlines); + Context::getContext().getLimits(maxrows, maxlines); // Adjust for fluff in the output. if (maxlines) - maxlines -= table_header - + (Context::getContext ().verbose ("blank") ? 1 : 0) - + (Context::getContext ().verbose ("footnote") ? Context::getContext ().footnotes.size () : 0) - + (Context::getContext ().verbose ("affected") ? 1 : 0) - + Context::getContext ().config.getInteger ("reserved.lines"); // For prompt, etc. + maxlines -= + table_header + (Context::getContext().verbose("blank") ? 1 : 0) + + (Context::getContext().verbose("footnote") ? Context::getContext().footnotes.size() : 0) + + (Context::getContext().verbose("affected") ? 1 : 0) + + Context::getContext().config.getInteger("reserved.lines"); // For prompt, etc. // Render. std::stringstream out; - if (filtered.size ()) - { - view.truncateRows (maxrows); - view.truncateLines (maxlines); + if (filtered.size()) { + view.truncateRows(maxrows); + view.truncateLines(maxlines); - out << optionalBlankLine () - << view.render (filtered, sequence) - << optionalBlankLine (); + out << optionalBlankLine() << view.render(filtered, sequence) << optionalBlankLine(); // Print the number of rendered tasks - if (Context::getContext ().verbose ("affected")) - { - out << (filtered.size () == 1 - ? "1 task" - : format ("{1} tasks", filtered.size ())); + if (Context::getContext().verbose("affected")) { + out << (filtered.size() == 1 ? "1 task" : format("{1} tasks", filtered.size())); - if (maxrows && maxrows < (int)filtered.size ()) - out << ", " << format ("{1} shown", maxrows); + if (maxrows && maxrows < (int)filtered.size()) out << ", " << format("{1} shown", maxrows); - if (maxlines && maxlines < (int)filtered.size ()) - out << ", " - << format ("truncated to {1} lines", maxlines - table_header); + if (maxlines && maxlines < (int)filtered.size()) + out << ", " << format("truncated to {1} lines", maxlines - table_header); out << '\n'; } - } - else - { - Context::getContext ().footnote ("No matches."); + } else { + Context::getContext().footnote("No matches."); rc = 1; } // Inform user about the new release highlights if not presented yet - Version news_version(Context::getContext ().config.get ("news.version")); + Version news_version(Context::getContext().config.get("news.version")); Version current_version = Version::Current(); - auto should_nag = news_version != current_version && Context::getContext ().verbose ("news"); - if (should_nag) - { + auto should_nag = news_version != current_version && Context::getContext().verbose("news"); + if (should_nag) { std::ostringstream notice; - notice << "Recently upgraded to " << current_version << ". " - "Please run 'task news' to read highlights about the new release."; - if (Context::getContext ().verbose ("footnote")) - Context::getContext ().footnote (notice.str()); - else if (Context::getContext ().verbose ("header")) - Context::getContext ().header (notice.str()); + notice << "Recently upgraded to " << current_version + << ". " + "Please run 'task news' to read highlights about the new release."; + if (Context::getContext().verbose("footnote")) + Context::getContext().footnote(notice.str()); + else if (Context::getContext().verbose("header")) + Context::getContext().header(notice.str()); } - std::string location = (Context::getContext ().data_dir); - File pending_data = File (location + "/pending.data"); + std::string location = (Context::getContext().data_dir); + File pending_data = File(location + "/pending.data"); if (pending_data.exists()) { - Color warning = Color (Context::getContext ().config.get ("color.warning")); - std::cerr << warning.colorize ( - format ("Found existing '*.data' files in {1}", location)) << "\n"; + Color warning = Color(Context::getContext().config.get("color.warning")); + std::cerr << warning.colorize(format("Found existing '*.data' files in {1}", location)) << "\n"; std::cerr << " Taskwarrior's storage format changed in 3.0, requiring a manual migration.\n"; std::cerr << " See https://github.com/GothenburgBitFactory/taskwarrior/releases.\n"; } - feedback_backlog (); - output = out.str (); + feedback_backlog(); + output = out.str(); return rc; } //////////////////////////////////////////////////////////////////////////////// -void CmdCustom::validateReportColumns (std::vector & columns) -{ - for (auto& col : columns) - legacyColumnMap (col); +void CmdCustom::validateReportColumns(std::vector& columns) { + for (auto& col : columns) legacyColumnMap(col); } //////////////////////////////////////////////////////////////////////////////// -void CmdCustom::validateSortColumns (std::vector & columns) -{ - for (auto& col : columns) - legacySortColumnMap (col); +void CmdCustom::validateSortColumns(std::vector& columns) { + for (auto& col : columns) legacySortColumnMap(col); } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/commands/CmdCustom.h b/src/commands/CmdCustom.h index 521876d65..eeefe6302 100644 --- a/src/commands/CmdCustom.h +++ b/src/commands/CmdCustom.h @@ -27,19 +27,19 @@ #ifndef INCLUDED_CMDCUSTOM #define INCLUDED_CMDCUSTOM -#include #include -class CmdCustom : public Command -{ -public: - CmdCustom (const std::string&, const std::string&, const std::string&); - bool uses_context () const override; - int execute (std::string&) override; +#include -private: - void validateReportColumns (std::vector &); - void validateSortColumns (std::vector &); +class CmdCustom : public Command { + public: + CmdCustom(const std::string&, const std::string&, const std::string&); + bool uses_context() const override; + int execute(std::string&) override; + + private: + void validateReportColumns(std::vector&); + void validateSortColumns(std::vector&); }; #endif diff --git a/src/commands/CmdDelete.cpp b/src/commands/CmdDelete.cpp index b27690c81..3026bd05d 100644 --- a/src/commands/CmdDelete.cpp +++ b/src/commands/CmdDelete.cpp @@ -28,165 +28,142 @@ // cmake.h include header must come first #include -#include #include #include -#include #include #include +#include -#define STRING_CMD_DELETE_TASK_R "Deleting recurring task {1} '{2}'." -#define STRING_CMD_DELETE_CONFIRM_R "This is a recurring task. Do you want to delete all pending recurrences of this same task?" +#include + +#define STRING_CMD_DELETE_TASK_R "Deleting recurring task {1} '{2}'." +#define STRING_CMD_DELETE_CONFIRM_R \ + "This is a recurring task. Do you want to delete all pending recurrences of this same task?" //////////////////////////////////////////////////////////////////////////////// -CmdDelete::CmdDelete () -{ - _keyword = "delete"; - _usage = "task delete "; - _description = "Deletes the specified task"; - _read_only = false; - _displays_id = false; - _needs_confirm = true; - _needs_gc = false; - _uses_context = true; - _accepts_filter = true; +CmdDelete::CmdDelete() { + _keyword = "delete"; + _usage = "task delete "; + _description = "Deletes the specified task"; + _read_only = false; + _displays_id = false; + _needs_confirm = true; + _needs_gc = false; + _uses_context = true; + _accepts_filter = true; _accepts_modifications = true; _accepts_miscellaneous = false; - _category = Command::Category::operation; + _category = Command::Category::operation; } //////////////////////////////////////////////////////////////////////////////// -int CmdDelete::execute (std::string&) -{ +int CmdDelete::execute(std::string&) { auto rc = 0; auto count = 0; // Apply filter. Filter filter; - std::vector filtered; - filter.subset (filtered); - if (filtered.size () == 0) - { - Context::getContext ().footnote ("No tasks specified."); + std::vector filtered; + filter.subset(filtered); + if (filtered.size() == 0) { + Context::getContext().footnote("No tasks specified."); return 1; } // Accumulated project change notifications. - std::map projectChanges; + std::map projectChanges; - if(filtered.size() > 1) { + if (filtered.size() > 1) { feedback_affected("This command will alter {1} tasks.", filtered.size()); } - for (auto& task : filtered) - { - Task before (task); + for (auto& task : filtered) { + Task before(task); - if (task.getStatus () != Task::deleted) - { + if (task.getStatus() != Task::deleted) { // Delete the specified task. std::string question; - question = format ("Delete task {1} '{2}'?", - task.identifier (true), - task.get ("description")); + question = format("Delete task {1} '{2}'?", task.identifier(true), task.get("description")); - task.modify (Task::modAnnotate); - task.setStatus (Task::deleted); - if (! task.has ("end")) - task.setAsNow ("end"); + task.modify(Task::modAnnotate); + task.setStatus(Task::deleted); + if (!task.has("end")) task.setAsNow("end"); - if (permission (question, filtered.size ())) - { - updateRecurrenceMask (task); + if (permission(question, filtered.size())) { + updateRecurrenceMask(task); ++count; - Context::getContext ().tdb2.modify (task); - feedback_affected ("Deleting task {1} '{2}'.", task); - feedback_unblocked (task); - dependencyChainOnComplete (task); - if (Context::getContext ().verbose ("project")) - projectChanges[task.get ("project")] = onProjectChange (task); + Context::getContext().tdb2.modify(task); + feedback_affected("Deleting task {1} '{2}'.", task); + feedback_unblocked(task); + dependencyChainOnComplete(task); + if (Context::getContext().verbose("project")) + projectChanges[task.get("project")] = onProjectChange(task); // Delete siblings. - if (task.has ("parent")) - { - if ((Context::getContext ().config.get ("recurrence.confirmation") == "prompt" - && confirm (STRING_CMD_DELETE_CONFIRM_R)) || - Context::getContext ().config.getBoolean ("recurrence.confirmation")) - { - std::vector siblings = Context::getContext ().tdb2.siblings (task); - for (auto& sibling : siblings) - { - sibling.modify (Task::modAnnotate); - sibling.setStatus (Task::deleted); - if (! sibling.has ("end")) - sibling.setAsNow ("end"); + if (task.has("parent")) { + if ((Context::getContext().config.get("recurrence.confirmation") == "prompt" && + confirm(STRING_CMD_DELETE_CONFIRM_R)) || + Context::getContext().config.getBoolean("recurrence.confirmation")) { + std::vector siblings = Context::getContext().tdb2.siblings(task); + for (auto& sibling : siblings) { + sibling.modify(Task::modAnnotate); + sibling.setStatus(Task::deleted); + if (!sibling.has("end")) sibling.setAsNow("end"); - updateRecurrenceMask (sibling); - Context::getContext ().tdb2.modify (sibling); - feedback_affected (STRING_CMD_DELETE_TASK_R, sibling); - feedback_unblocked (sibling); + updateRecurrenceMask(sibling); + Context::getContext().tdb2.modify(sibling); + feedback_affected(STRING_CMD_DELETE_TASK_R, sibling); + feedback_unblocked(sibling); ++count; } // Delete the parent Task parent; - Context::getContext ().tdb2.get (task.get ("parent"), parent); - parent.setStatus (Task::deleted); - if (! parent.has ("end")) - parent.setAsNow ("end"); + Context::getContext().tdb2.get(task.get("parent"), parent); + parent.setStatus(Task::deleted); + if (!parent.has("end")) parent.setAsNow("end"); - Context::getContext ().tdb2.modify (parent); + Context::getContext().tdb2.modify(parent); } } // Task potentially has child tasks - optionally delete them. - else - { - std::vector children = Context::getContext ().tdb2.children (task); + else { + std::vector children = Context::getContext().tdb2.children(task); if (children.size() && - ((Context::getContext ().config.get ("recurrence.confirmation") == "prompt" - && confirm (STRING_CMD_DELETE_CONFIRM_R)) || - Context::getContext ().config.getBoolean ("recurrence.confirmation"))) - { - for (auto& child : children) - { - child.modify (Task::modAnnotate); - child.setStatus (Task::deleted); - if (! child.has ("end")) - child.setAsNow ("end"); + ((Context::getContext().config.get("recurrence.confirmation") == "prompt" && + confirm(STRING_CMD_DELETE_CONFIRM_R)) || + Context::getContext().config.getBoolean("recurrence.confirmation"))) { + for (auto& child : children) { + child.modify(Task::modAnnotate); + child.setStatus(Task::deleted); + if (!child.has("end")) child.setAsNow("end"); - updateRecurrenceMask (child); - Context::getContext ().tdb2.modify (child); - feedback_affected (STRING_CMD_DELETE_TASK_R, child); - feedback_unblocked (child); + updateRecurrenceMask(child); + Context::getContext().tdb2.modify(child); + feedback_affected(STRING_CMD_DELETE_TASK_R, child); + feedback_unblocked(child); ++count; } } } - } - else - { + } else { std::cout << "Task not deleted.\n"; rc = 1; - if (_permission_quit) - break; + if (_permission_quit) break; } - } - else - { - std::cout << format ("Task {1} '{2}' is not deletable.", - task.identifier (true), - task.get ("description")) - << '\n'; + } else { + std::cout << format("Task {1} '{2}' is not deletable.", task.identifier(true), + task.get("description")) + << '\n'; rc = 1; } } // Now list the project changes. for (const auto& change : projectChanges) - if (change.first != "") - Context::getContext ().footnote (change.second); + if (change.first != "") Context::getContext().footnote(change.second); - feedback_affected (count == 1 ? "Deleted {1} task." : "Deleted {1} tasks.", count); + feedback_affected(count == 1 ? "Deleted {1} task." : "Deleted {1} tasks.", count); return rc; } diff --git a/src/commands/CmdDelete.h b/src/commands/CmdDelete.h index 94345e622..2cc604b02 100644 --- a/src/commands/CmdDelete.h +++ b/src/commands/CmdDelete.h @@ -27,14 +27,14 @@ #ifndef INCLUDED_CMDDELETE #define INCLUDED_CMDDELETE -#include #include -class CmdDelete : public Command -{ -public: - CmdDelete (); - int execute (std::string&); +#include + +class CmdDelete : public Command { + public: + CmdDelete(); + int execute(std::string&); }; #endif diff --git a/src/commands/CmdDenotate.cpp b/src/commands/CmdDenotate.cpp index 1b3a56916..363834843 100644 --- a/src/commands/CmdDenotate.cpp +++ b/src/commands/CmdDenotate.cpp @@ -28,143 +28,124 @@ // cmake.h include header must come first #include -#include #include #include -#include #include -#include #include +#include +#include -#define STRING_CMD_DENO_NO "Task not denotated." -#define STRING_CMD_DENO_1 "Denotated {1} task." -#define STRING_CMD_DENO_N "Denotated {1} tasks." +#include + +#define STRING_CMD_DENO_NO "Task not denotated." +#define STRING_CMD_DENO_1 "Denotated {1} task." +#define STRING_CMD_DENO_N "Denotated {1} tasks." //////////////////////////////////////////////////////////////////////////////// -CmdDenotate::CmdDenotate () -{ - _keyword = "denotate"; - _usage = "task denotate "; - _description = "Deletes an annotation"; - _read_only = false; - _displays_id = false; - _needs_gc = false; - _uses_context = true; - _accepts_filter = true; +CmdDenotate::CmdDenotate() { + _keyword = "denotate"; + _usage = "task denotate "; + _description = "Deletes an annotation"; + _read_only = false; + _displays_id = false; + _needs_gc = false; + _uses_context = true; + _accepts_filter = true; _accepts_modifications = false; _accepts_miscellaneous = true; - _category = Command::Category::operation; + _category = Command::Category::operation; } //////////////////////////////////////////////////////////////////////////////// -int CmdDenotate::execute (std::string&) -{ +int CmdDenotate::execute(std::string&) { auto rc = 0; auto count = 0; - auto sensitive = Context::getContext ().config.getBoolean ("search.case.sensitive"); + auto sensitive = Context::getContext().config.getBoolean("search.case.sensitive"); // Apply filter. Filter filter; - std::vector filtered; - filter.subset (filtered); - if (filtered.size () == 0) - { - Context::getContext ().footnote ("No tasks specified."); + std::vector filtered; + filter.subset(filtered); + if (filtered.size() == 0) { + Context::getContext().footnote("No tasks specified."); return 1; } // Extract all the ORIGINAL MODIFICATION args as simple text patterns. std::string pattern = ""; - for (auto& a : Context::getContext ().cli2._args) - { - if (a.hasTag ("MISCELLANEOUS")) - { - if (pattern != "") - pattern += ' '; + for (auto& a : Context::getContext().cli2._args) { + if (a.hasTag("MISCELLANEOUS")) { + if (pattern != "") pattern += ' '; - pattern += a.attribute ("raw"); + pattern += a.attribute("raw"); } } // Accumulated project change notifications. - std::map projectChanges; + std::map projectChanges; - if(filtered.size() > 1) { + if (filtered.size() > 1) { feedback_affected("This command will alter {1} tasks.", filtered.size()); } - for (auto& task : filtered) - { - Task before (task); + for (auto& task : filtered) { + Task before(task); - auto annotations = task.getAnnotations (); + auto annotations = task.getAnnotations(); - if (annotations.size () == 0) - throw std::string ("The specified task has no annotations that can be deleted."); + if (annotations.size() == 0) + throw std::string("The specified task has no annotations that can be deleted."); std::string anno; auto match = false; - for (auto i = annotations.begin (); i != annotations.end (); ++i) - { - if (i->second == pattern) - { + for (auto i = annotations.begin(); i != annotations.end(); ++i) { + if (i->second == pattern) { match = true; anno = i->second; - annotations.erase (i); - task.setAnnotations (annotations); + annotations.erase(i); + task.setAnnotations(annotations); break; } } - if (! match) - { - for (auto i = annotations.begin (); i != annotations.end (); ++i) - { - auto loc = find (i->second, pattern, sensitive); - if (loc != std::string::npos) - { + if (!match) { + for (auto i = annotations.begin(); i != annotations.end(); ++i) { + auto loc = find(i->second, pattern, sensitive); + if (loc != std::string::npos) { anno = i->second; - annotations.erase (i); - task.setAnnotations (annotations); + annotations.erase(i); + task.setAnnotations(annotations); break; } } } - if (before.getAnnotations () != task.getAnnotations ()) - { - auto question = format ("Denotate task {1} '{2}'?", - task.identifier (true), - task.get ("description")); + if (before.getAnnotations() != task.getAnnotations()) { + auto question = + format("Denotate task {1} '{2}'?", task.identifier(true), task.get("description")); - if (permission (before.diff (task) + question, filtered.size ())) - { + if (permission(before.diff(task) + question, filtered.size())) { ++count; - Context::getContext ().tdb2.modify (task); - feedback_affected (format ("Found annotation '{1}' and deleted it.", anno)); - if (Context::getContext ().verbose ("project")) - projectChanges[task.get ("project")] = onProjectChange (task, false); - } - else - { + Context::getContext().tdb2.modify(task); + feedback_affected(format("Found annotation '{1}' and deleted it.", anno)); + if (Context::getContext().verbose("project")) + projectChanges[task.get("project")] = onProjectChange(task, false); + } else { std::cout << STRING_CMD_DENO_NO << '\n'; rc = 1; - if (_permission_quit) - break; + if (_permission_quit) break; } - } - else - { - std::cout << format ("Did not find any matching annotation to be deleted for '{1}'.\n", pattern); + } else { + std::cout << format("Did not find any matching annotation to be deleted for '{1}'.\n", + pattern); rc = 1; } } // Now list the project changes. for (const auto& change : projectChanges) - if (change.first != "") - Context::getContext ().footnote (change.second); + if (change.first != "") Context::getContext().footnote(change.second); - feedback_affected (count == 1 ? STRING_CMD_DENO_1 : STRING_CMD_DENO_N, count); + feedback_affected(count == 1 ? STRING_CMD_DENO_1 : STRING_CMD_DENO_N, count); return rc; } diff --git a/src/commands/CmdDenotate.h b/src/commands/CmdDenotate.h index 87ffd0f17..e45c9e2b1 100644 --- a/src/commands/CmdDenotate.h +++ b/src/commands/CmdDenotate.h @@ -27,14 +27,14 @@ #ifndef INCLUDED_CMDDENOTATE #define INCLUDED_CMDDENOTATE -#include #include -class CmdDenotate : public Command -{ -public: - CmdDenotate (); - int execute (std::string&); +#include + +class CmdDenotate : public Command { + public: + CmdDenotate(); + int execute(std::string&); }; #endif diff --git a/src/commands/CmdDiagnostics.cpp b/src/commands/CmdDiagnostics.cpp index 7901524cf..e4ac10bae 100644 --- a/src/commands/CmdDiagnostics.cpp +++ b/src/commands/CmdDiagnostics.cpp @@ -28,33 +28,33 @@ // cmake.h include header must come first #include -#include -#include -#include +#include +#include +#include +#include #include #include -#include -#include -#include -#include + +#include +#include +#include #ifdef HAVE_COMMIT #include #endif //////////////////////////////////////////////////////////////////////////////// -CmdDiagnostics::CmdDiagnostics () -{ - _keyword = "diagnostics"; - _usage = "task diagnostics"; - _description = "Platform, build and environment details"; - _read_only = true; - _displays_id = false; - _needs_gc = false; - _uses_context = false; - _accepts_filter = false; +CmdDiagnostics::CmdDiagnostics() { + _keyword = "diagnostics"; + _usage = "task diagnostics"; + _description = "Platform, build and environment details"; + _read_only = true; + _displays_id = false; + _needs_gc = false; + _uses_context = false; + _accepts_filter = false; _accepts_modifications = false; _accepts_miscellaneous = false; - _category = Command::Category::misc; + _category = Command::Category::misc; } //////////////////////////////////////////////////////////////////////////////// @@ -62,26 +62,19 @@ CmdDiagnostics::CmdDiagnostics () // // Although this will change over time, initially this command will answer the // kind of questions we always have to ask whenever something is wrong. -int CmdDiagnostics::execute (std::string& output) -{ +int CmdDiagnostics::execute(std::string& output) { Color bold; - if (Context::getContext ().color ()) - bold = Color ("bold"); + if (Context::getContext().color()) bold = Color("bold"); std::stringstream out; - out << '\n' - << bold.colorize (PACKAGE_STRING) - << '\n'; + out << '\n' << bold.colorize(PACKAGE_STRING) << '\n'; - out << " Platform: " << osName () - << "\n\n"; + out << " Platform: " << osName() << "\n\n"; // Compiler. - out << bold.colorize ("Compiler") - << '\n' + out << bold.colorize("Compiler") << '\n' #ifdef __VERSION__ - << " Version: " - << __VERSION__ << '\n' + << " Version: " << __VERSION__ << '\n' #endif << " Caps:" #ifdef __STDC__ @@ -105,20 +98,13 @@ int CmdDiagnostics::execute (std::string& output) #ifdef _LP64 << " +LP64" #endif - << " +c" << 8 * sizeof (char) - << " +i" << 8 * sizeof (int) - << " +l" << 8 * sizeof (long) - << " +vp" << 8 * sizeof (void*) - << " +time_t" << 8 * sizeof (time_t) - << '\n'; + << " +c" << 8 * sizeof(char) << " +i" << 8 * sizeof(int) << " +l" << 8 * sizeof(long) + << " +vp" << 8 * sizeof(void*) << " +time_t" << 8 * sizeof(time_t) << '\n'; // Compiler compliance level. - out << " Compliance: " - << cppCompliance () - << "\n\n"; + out << " Compliance: " << cppCompliance() << "\n\n"; - out << bold.colorize ("Build Features") - << '\n' + out << bold.colorize("Build Features") << '\n' #ifdef HAVE_COMMIT << " Commit: " << COMMIT << '\n' @@ -142,205 +128,146 @@ int CmdDiagnostics::execute (std::string& output) << "\n\n"; // Config: .taskrc found, readable, writable - File rcFile (Context::getContext ().config.file ()); - out << bold.colorize ("Configuration") - << '\n' - << " File: " << rcFile._data << ' ' - << (rcFile.exists () - ? "(found)" - : "(missing)") - << ", " << rcFile.size () << ' ' << "bytes" - << ", mode " - << std::setbase (8) - << rcFile.mode () - << '\n'; + File rcFile(Context::getContext().config.file()); + out << bold.colorize("Configuration") << '\n' + << " File: " << rcFile._data << ' ' << (rcFile.exists() ? "(found)" : "(missing)") + << ", " << rcFile.size() << ' ' << "bytes" + << ", mode " << std::setbase(8) << rcFile.mode() << '\n'; // Config: data.location found, readable, writable - File location (Context::getContext ().config.get ("data.location")); - out << " Data: " << location._data << ' ' - << (location.exists () - ? "(found)" - : "(missing)") - << ", " << (location.is_directory () ? "dir" : "?") - << ", mode " - << std::setbase (8) - << location.mode () - << '\n'; + File location(Context::getContext().config.get("data.location")); + out << " Data: " << location._data << ' ' << (location.exists() ? "(found)" : "(missing)") + << ", " << (location.is_directory() ? "dir" : "?") << ", mode " << std::setbase(8) + << location.mode() << '\n'; - char* env = getenv ("TASKRC"); - if (env) - out << " TASKRC: " - << env - << '\n'; + char* env = getenv("TASKRC"); + if (env) out << " TASKRC: " << env << '\n'; - env = getenv ("TASKDATA"); - if (env) - out << " TASKDATA: " - << env - << '\n'; + env = getenv("TASKDATA"); + if (env) out << " TASKDATA: " << env << '\n'; - out << " GC: " - << (Context::getContext ().config.getBoolean ("gc") - ? "Enabled" - : "Disabled") + out << " GC: " << (Context::getContext().config.getBoolean("gc") ? "Enabled" : "Disabled") << '\n'; // Determine rc.editor/$EDITOR/$VISUAL. char* peditor; - if (Context::getContext ().config.get ("editor") != "") - out << " rc.editor: " << Context::getContext ().config.get ("editor") << '\n'; - else if ((peditor = getenv ("VISUAL")) != nullptr) + if (Context::getContext().config.get("editor") != "") + out << " rc.editor: " << Context::getContext().config.get("editor") << '\n'; + else if ((peditor = getenv("VISUAL")) != nullptr) out << " $VISUAL: " << peditor << '\n'; - else if ((peditor = getenv ("EDITOR")) != nullptr) + else if ((peditor = getenv("EDITOR")) != nullptr) out << " $EDITOR: " << peditor << '\n'; // Display hook status. Path hookLocation; - if (Context::getContext ().config.has ("hooks.location")) - { - hookLocation = Path (Context::getContext ().config.get ("hooks.location")); - } - else - { - hookLocation = Path (Context::getContext ().config.get ("data.location")); + if (Context::getContext().config.has("hooks.location")) { + hookLocation = Path(Context::getContext().config.get("hooks.location")); + } else { + hookLocation = Path(Context::getContext().config.get("data.location")); hookLocation += "hooks"; } - out << bold.colorize ("Hooks") - << '\n' + out << bold.colorize("Hooks") << '\n' << " System: " - << (Context::getContext ().config.getBoolean ("hooks") ? "Enabled" : "Disabled") - << '\n' - << " Location: " - << static_cast (hookLocation) - << '\n'; + << (Context::getContext().config.getBoolean("hooks") ? "Enabled" : "Disabled") << '\n' + << " Location: " << static_cast(hookLocation) << '\n'; - auto hooks = Context::getContext ().hooks.list (); - if (hooks.size ()) - { + auto hooks = Context::getContext().hooks.list(); + if (hooks.size()) { unsigned int longest = 0; for (auto& hook : hooks) - if (hook.length () > longest) - longest = hook.length (); - longest -= hookLocation._data.length () + 1; + if (hook.length() > longest) longest = hook.length(); + longest -= hookLocation._data.length() + 1; out << " Active: "; int count = 0; - for (auto& hook : hooks) - { - Path p (hook); - if (! p.is_directory ()) - { - auto name = p.name (); + for (auto& hook : hooks) { + Path p(hook); + if (!p.is_directory()) { + auto name = p.name(); - if (p.executable () && - (name.substr (0, 6) == "on-add" || - name.substr (0, 9) == "on-modify" || - name.substr (0, 9) == "on-launch" || - name.substr (0, 7) == "on-exit")) - { + if (p.executable() && + (name.substr(0, 6) == "on-add" || name.substr(0, 9) == "on-modify" || + name.substr(0, 9) == "on-launch" || name.substr(0, 7) == "on-exit")) { out << (count++ ? " " : ""); - out.width (longest); - out << std::left << name - << " (executable)" - << (p.is_link () ? " (symlink)" : "") - << '\n'; + out.width(longest); + out << std::left << name << " (executable)" << (p.is_link() ? " (symlink)" : "") << '\n'; } } } - if (! count) - out << '\n'; + if (!count) out << '\n'; out << " Inactive: "; count = 0; - for (auto& hook : hooks) - { - Path p (hook); - if (! p.is_directory ()) - { - auto name = p.name (); + for (auto& hook : hooks) { + Path p(hook); + if (!p.is_directory()) { + auto name = p.name(); - if (! p.executable () || - (name.substr (0, 6) != "on-add" && - name.substr (0, 9) != "on-modify" && - name.substr (0, 9) != "on-launch" && - name.substr (0, 7) != "on-exit")) - { + if (!p.executable() || + (name.substr(0, 6) != "on-add" && name.substr(0, 9) != "on-modify" && + name.substr(0, 9) != "on-launch" && name.substr(0, 7) != "on-exit")) { out << (count++ ? " " : ""); - out.width (longest); - out << std::left << name - << (p.executable () ? " (executable)" : " (not executable)") - << (p.is_link () ? " (symlink)" : "") - << ((name.substr (0, 6) == "on-add" || - name.substr (0, 9) == "on-modify" || - name.substr (0, 9) == "on-launch" || - name.substr (0, 7) == "on-exit") ? "" : "unrecognized hook name") + out.width(longest); + out << std::left << name << (p.executable() ? " (executable)" : " (not executable)") + << (p.is_link() ? " (symlink)" : "") + << ((name.substr(0, 6) == "on-add" || name.substr(0, 9) == "on-modify" || + name.substr(0, 9) == "on-launch" || name.substr(0, 7) == "on-exit") + ? "" + : "unrecognized hook name") << '\n'; } } } - if (! count) - out << '\n'; - } - else + if (!count) out << '\n'; + } else out << " (-none-)\n"; out << '\n'; // Verify UUIDs are all unique. - out << bold.colorize ("Tests") - << '\n'; + out << bold.colorize("Tests") << '\n'; // Report terminal dimensions. - out << " Terminal: " - << Context::getContext ().getWidth () - << 'x' - << Context::getContext ().getHeight () - << '\n'; + out << " Terminal: " << Context::getContext().getWidth() << 'x' + << Context::getContext().getHeight() << '\n'; // Check all the UUID references - auto all = Context::getContext ().tdb2.all_tasks (); + auto all = Context::getContext().tdb2.all_tasks(); bool noBrokenRefs = true; - out << " Broken ref: " - << format ("Scanned {1} tasks for broken references:", all.size ()) - << '\n'; + out << " Broken ref: " << format("Scanned {1} tasks for broken references:", all.size()) << '\n'; - for (auto& task : all) - { + for (auto& task : all) { // Check dependencies - for (auto& uuid : task.getDependencyUUIDs ()) - { - if (! Context::getContext ().tdb2.has (uuid)) - { + for (auto& uuid : task.getDependencyUUIDs()) { + if (!Context::getContext().tdb2.has(uuid)) { out << " " - << format ("Task {1} depends on nonexistent task: {2}", task.get ("uuid"), uuid) - << '\n'; + << format("Task {1} depends on nonexistent task: {2}", task.get("uuid"), uuid) << '\n'; noBrokenRefs = false; } } // Check recurrence parent - auto parentUUID = task.get ("parent"); + auto parentUUID = task.get("parent"); - if (parentUUID != "" && ! Context::getContext ().tdb2.has (parentUUID)) - { + if (parentUUID != "" && !Context::getContext().tdb2.has(parentUUID)) { out << " " - << format ("Task {1} has nonexistent recurrence template {2}", task.get ("uuid"), parentUUID) + << format("Task {1} has nonexistent recurrence template {2}", task.get("uuid"), + parentUUID) << '\n'; noBrokenRefs = false; } } - if (noBrokenRefs) - out << " No broken references found\n"; + if (noBrokenRefs) out << " No broken references found\n"; out << '\n'; - output = out.str (); + output = out.str(); return 0; } diff --git a/src/commands/CmdDiagnostics.h b/src/commands/CmdDiagnostics.h index 0cb399e84..0d4adf62b 100644 --- a/src/commands/CmdDiagnostics.h +++ b/src/commands/CmdDiagnostics.h @@ -27,14 +27,14 @@ #ifndef INCLUDED_CMDDIAGNOSTICS #define INCLUDED_CMDDIAGNOSTICS -#include #include -class CmdDiagnostics : public Command -{ -public: - CmdDiagnostics (); - int execute (std::string&); +#include + +class CmdDiagnostics : public Command { + public: + CmdDiagnostics(); + int execute(std::string&); }; #endif diff --git a/src/commands/CmdDone.cpp b/src/commands/CmdDone.cpp index e6b8af922..1e3638d33 100644 --- a/src/commands/CmdDone.cpp +++ b/src/commands/CmdDone.cpp @@ -28,118 +28,102 @@ // cmake.h include header must come first #include -#include #include #include -#include #include #include +#include + +#include //////////////////////////////////////////////////////////////////////////////// -CmdDone::CmdDone () -{ - _keyword = "done"; - _usage = "task done "; - _description = "Marks the specified task as completed"; - _read_only = false; - _displays_id = false; - _needs_gc = false; - _uses_context = true; - _accepts_filter = true; +CmdDone::CmdDone() { + _keyword = "done"; + _usage = "task done "; + _description = "Marks the specified task as completed"; + _read_only = false; + _displays_id = false; + _needs_gc = false; + _uses_context = true; + _accepts_filter = true; _accepts_modifications = true; _accepts_miscellaneous = false; - _category = Command::Category::operation; + _category = Command::Category::operation; } //////////////////////////////////////////////////////////////////////////////// -int CmdDone::execute (std::string&) -{ +int CmdDone::execute(std::string&) { auto rc = 0; auto count = 0; // Apply filter. Filter filter; - std::vector filtered; - filter.subset (filtered); - if (filtered.size () == 0) - { - Context::getContext ().footnote ("No tasks specified."); + std::vector filtered; + filter.subset(filtered); + if (filtered.size() == 0) { + Context::getContext().footnote("No tasks specified."); return 1; } // Accumulated project change notifications. - std::map projectChanges; + std::map projectChanges; - if(filtered.size() > 1) { + if (filtered.size() > 1) { feedback_affected("This command will alter {1} tasks.", filtered.size()); } - std::vector modified; - for (auto& task : filtered) - { - Task before (task); + std::vector modified; + for (auto& task : filtered) { + Task before(task); - if (task.getStatus () == Task::pending || - task.getStatus () == Task::waiting) - { + if (task.getStatus() == Task::pending || task.getStatus() == Task::waiting) { // Complete the specified task. - std::string question = format ("Complete task {1} '{2}'?", - task.identifier (true), - task.get ("description")); + std::string question = + format("Complete task {1} '{2}'?", task.identifier(true), task.get("description")); - task.modify (Task::modAnnotate); - task.setStatus (Task::completed); - if (! task.has ("end")) - task.setAsNow ("end"); + task.modify(Task::modAnnotate); + task.setStatus(Task::completed); + if (!task.has("end")) task.setAsNow("end"); // Stop the task, if started. - if (task.has ("start")) - { - task.remove ("start"); - if (Context::getContext ().config.getBoolean ("journal.time")) - task.addAnnotation (Context::getContext ().config.get ("journal.time.stop.annotation")); + if (task.has("start")) { + task.remove("start"); + if (Context::getContext().config.getBoolean("journal.time")) + task.addAnnotation(Context::getContext().config.get("journal.time.stop.annotation")); } - if (permission (before.diff (task) + question, filtered.size ())) - { - updateRecurrenceMask (task); - Context::getContext ().tdb2.modify (task); + if (permission(before.diff(task) + question, filtered.size())) { + updateRecurrenceMask(task); + Context::getContext().tdb2.modify(task); ++count; - feedback_affected ("Completed task {1} '{2}'.", task); - feedback_unblocked (task); - dependencyChainOnComplete (task); - if (Context::getContext ().verbose ("project")) - projectChanges[task.get ("project")] = onProjectChange (task); + feedback_affected("Completed task {1} '{2}'.", task); + feedback_unblocked(task); + dependencyChainOnComplete(task); + if (Context::getContext().verbose("project")) + projectChanges[task.get("project")] = onProjectChange(task); // Save unmodified task for potential nagging later modified.push_back(before); - } - else - { + } else { std::cout << "Task not completed.\n"; rc = 1; - if (_permission_quit) - break; + if (_permission_quit) break; } - } - else - { - std::cout << format ("Task {1} '{2}' is neither pending nor waiting.", - task.identifier (true), - task.get ("description")) + } else { + std::cout << format("Task {1} '{2}' is neither pending nor waiting.", task.identifier(true), + task.get("description")) << '\n'; rc = 1; } } - nag (modified); + nag(modified); // Now list the project changes. for (const auto& change : projectChanges) - if (change.first != "") - Context::getContext ().footnote (change.second); + if (change.first != "") Context::getContext().footnote(change.second); - feedback_affected (count == 1 ? "Completed {1} task." : "Completed {1} tasks.", count); + feedback_affected(count == 1 ? "Completed {1} task." : "Completed {1} tasks.", count); return rc; } diff --git a/src/commands/CmdDone.h b/src/commands/CmdDone.h index 422a0e5e4..3aa4ce8b8 100644 --- a/src/commands/CmdDone.h +++ b/src/commands/CmdDone.h @@ -27,14 +27,14 @@ #ifndef INCLUDED_CMDDONE #define INCLUDED_CMDDONE -#include #include -class CmdDone : public Command -{ -public: - CmdDone (); - int execute (std::string&); +#include + +class CmdDone : public Command { + public: + CmdDone(); + int execute(std::string&); }; #endif diff --git a/src/commands/CmdDuplicate.cpp b/src/commands/CmdDuplicate.cpp index 386a301e7..381d6c368 100644 --- a/src/commands/CmdDuplicate.cpp +++ b/src/commands/CmdDuplicate.cpp @@ -28,119 +28,109 @@ // cmake.h include header must come first #include -#include #include #include #include -#include #include +#include + +#include //////////////////////////////////////////////////////////////////////////////// -CmdDuplicate::CmdDuplicate () -{ - _keyword = "duplicate"; - _usage = "task duplicate "; - _description = "Duplicates the specified tasks"; - _read_only = false; - _displays_id = false; - _needs_gc = false; - _uses_context = true; - _accepts_filter = true; +CmdDuplicate::CmdDuplicate() { + _keyword = "duplicate"; + _usage = "task duplicate "; + _description = "Duplicates the specified tasks"; + _read_only = false; + _displays_id = false; + _needs_gc = false; + _uses_context = true; + _accepts_filter = true; _accepts_modifications = true; _accepts_miscellaneous = false; - _category = Command::Category::operation; + _category = Command::Category::operation; } //////////////////////////////////////////////////////////////////////////////// -int CmdDuplicate::execute (std::string&) -{ +int CmdDuplicate::execute(std::string&) { auto rc = 0; auto count = 0; // Apply filter. Filter filter; - std::vector filtered; - filter.subset (filtered); - if (filtered.size () == 0) - { - Context::getContext ().footnote ("No tasks specified."); + std::vector filtered; + filter.subset(filtered); + if (filtered.size() == 0) { + Context::getContext().footnote("No tasks specified."); return 1; } // Accumulated project change notifications. - std::map projectChanges; + std::map projectChanges; - for (auto& task : filtered) - { + for (auto& task : filtered) { // Duplicate the specified task. - Task dup (task); - dup.id = 0; // Reset, and TDB2::add will set. - dup.set ("uuid", uuid ()); // Needs a new UUID. - dup.remove ("start"); // Does not inherit start date. - dup.remove ("end"); // Does not inherit end date. - dup.remove ("entry"); // Does not inherit entry date. + Task dup(task); + dup.id = 0; // Reset, and TDB2::add will set. + dup.set("uuid", uuid()); // Needs a new UUID. + dup.remove("start"); // Does not inherit start date. + dup.remove("end"); // Does not inherit end date. + dup.remove("entry"); // Does not inherit entry date. // When duplicating a child task, downgrade it to a plain task. - if (dup.has ("parent")) - { - dup.remove ("parent"); - dup.remove ("recur"); - dup.remove ("until"); - dup.remove ("imask"); - std::cout << format ("Note: task {1} was a recurring task. The duplicated task is not.", task.identifier ()) - << '\n'; + if (dup.has("parent")) { + dup.remove("parent"); + dup.remove("recur"); + dup.remove("until"); + dup.remove("imask"); + std::cout << format("Note: task {1} was a recurring task. The duplicated task is not.", + task.identifier()) + << '\n'; } // When duplicating a parent task, create a new parent task. - else if (dup.getStatus () == Task::recurring) - { - dup.remove ("mask"); - std::cout << format ("Note: task {1} was a parent recurring task. The duplicated task is too.", task.identifier ()) - << '\n'; + else if (dup.getStatus() == Task::recurring) { + dup.remove("mask"); + std::cout << format( + "Note: task {1} was a parent recurring task. The duplicated task is too.", + task.identifier()) + << '\n'; } - dup.setStatus (Task::pending); // Does not inherit status. + dup.setStatus(Task::pending); // Does not inherit status. // Must occur after Task::recurring check. - dup.modify (Task::modAnnotate); + dup.modify(Task::modAnnotate); - if (permission (format ("Duplicate task {1} '{2}'?", - task.identifier (true), - task.get ("description")), - filtered.size ())) - { - Context::getContext ().tdb2.add (dup); + if (permission( + format("Duplicate task {1} '{2}'?", task.identifier(true), task.get("description")), + filtered.size())) { + Context::getContext().tdb2.add(dup); ++count; - feedback_affected ("Duplicated task {1} '{2}'.", task); + feedback_affected("Duplicated task {1} '{2}'.", task); - auto status = dup.getStatus (); - if (Context::getContext ().verbose ("new-id") && - (status == Task::pending || - status == Task::waiting)) - std::cout << format ("Created task {1}.\n", dup.id); + auto status = dup.getStatus(); + if (Context::getContext().verbose("new-id") && + (status == Task::pending || status == Task::waiting)) + std::cout << format("Created task {1}.\n", dup.id); - else if (Context::getContext ().verbose ("new-uuid") && - status != Task::recurring) - std::cout << format ("Created task {1}.\n", dup.get ("uuid")); + else if (Context::getContext().verbose("new-uuid") && status != Task::recurring) + std::cout << format("Created task {1}.\n", dup.get("uuid")); - if (Context::getContext ().verbose ("project")) - projectChanges[task.get ("project")] = onProjectChange (task); - } - else - { + if (Context::getContext().verbose("project")) + projectChanges[task.get("project")] = onProjectChange(task); + } else { std::cout << "Task not duplicated.\n"; rc = 1; - if (_permission_quit) - break; + if (_permission_quit) break; } } // Now list the project changes. for (const auto& change : projectChanges) - if (change.first != "") - Context::getContext ().footnote (change.second); + if (change.first != "") Context::getContext().footnote(change.second); - feedback_affected (count == 1 ? "Duplicated {1} task." : "Duplicated {1} tasks.", count); + feedback_affected(count == 1 ? "Duplicated {1} task." : "Duplicated {1} tasks.", count); return rc; } diff --git a/src/commands/CmdDuplicate.h b/src/commands/CmdDuplicate.h index 7360faccc..b05a53ab1 100644 --- a/src/commands/CmdDuplicate.h +++ b/src/commands/CmdDuplicate.h @@ -27,14 +27,14 @@ #ifndef INCLUDED_CMDDUPLICATE #define INCLUDED_CMDDUPLICATE -#include #include -class CmdDuplicate : public Command -{ -public: - CmdDuplicate (); - int execute (std::string&); +#include + +class CmdDuplicate : public Command { + public: + CmdDuplicate(); + int execute(std::string&); }; #endif diff --git a/src/commands/CmdEdit.cpp b/src/commands/CmdEdit.cpp index 7e8c93023..acdd1ce4c 100644 --- a/src/commands/CmdEdit.cpp +++ b/src/commands/CmdEdit.cpp @@ -28,105 +28,94 @@ // cmake.h include header must come first #include -#include -#include -#include -#include -#include -#include -#include +#include #include #include -#include -#include #include -#include -#include -#include -#include -#include #include +#include +#include +#include +#include +#include +#include +#include -#define STRING_EDIT_START_MOD "Start date modified." -#define STRING_EDIT_SCHED_MOD "Scheduled date modified." -#define STRING_EDIT_DUE_MOD "Due date modified." -#define STRING_EDIT_UNTIL_MOD "Until date modified." -#define STRING_EDIT_WAIT_MOD "Wait date modified." +#include +#include +#include +#include +#include +#include + +#define STRING_EDIT_START_MOD "Start date modified." +#define STRING_EDIT_SCHED_MOD "Scheduled date modified." +#define STRING_EDIT_DUE_MOD "Due date modified." +#define STRING_EDIT_UNTIL_MOD "Until date modified." +#define STRING_EDIT_WAIT_MOD "Wait date modified." const std::string CmdEdit::ANNOTATION_EDIT_MARKER = "\n "; //////////////////////////////////////////////////////////////////////////////// -CmdEdit::CmdEdit () -{ - _keyword = "edit"; - _usage = "task edit"; - _description = "Launches an editor to modify a task directly"; - _read_only = false; - _displays_id = false; - _needs_gc = false; - _uses_context = true; - _accepts_filter = true; +CmdEdit::CmdEdit() { + _keyword = "edit"; + _usage = "task edit"; + _description = "Launches an editor to modify a task directly"; + _read_only = false; + _displays_id = false; + _needs_gc = false; + _uses_context = true; + _accepts_filter = true; _accepts_modifications = false; _accepts_miscellaneous = false; - _category = Command::Category::operation; + _category = Command::Category::operation; } //////////////////////////////////////////////////////////////////////////////// // 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. -int CmdEdit::execute (std::string&) -{ +int CmdEdit::execute(std::string&) { // Filter the tasks. - handleUntil (); - handleRecurrence (); + handleUntil(); + handleRecurrence(); Filter filter; - std::vector filtered; - filter.subset (filtered); + std::vector filtered; + filter.subset(filtered); - if (! filtered.size ()) - { - Context::getContext ().footnote ("No matches."); + if (!filtered.size()) { + Context::getContext().footnote("No matches."); return 1; } - unsigned int bulk = Context::getContext ().config.getInteger ("bulk"); + unsigned int bulk = Context::getContext().config.getInteger("bulk"); // If we are editing more than "bulk" tasks, ask for confirmation. // Bulk = 0 denotes infinite bulk. - if ((filtered.size () > bulk) && (bulk != 0)) - if (! confirm (format ("Do you wish to manually edit {1} tasks?", filtered.size ()))) - return 2; + if ((filtered.size() > bulk) && (bulk != 0)) + if (!confirm(format("Do you wish to manually edit {1} tasks?", filtered.size()))) return 2; // Find number of matching tasks. - for (auto& task : filtered) - { - auto result = editFile (task); + for (auto& task : filtered) { + auto result = editFile(task); if (result == CmdEdit::editResult::error) break; else if (result == CmdEdit::editResult::changes) - Context::getContext ().tdb2.modify (task); + Context::getContext().tdb2.modify(task); } return 0; } //////////////////////////////////////////////////////////////////////////////// -std::string CmdEdit::findValue ( - const std::string& text, - const std::string& name) -{ - auto found = text.find (name); - if (found != std::string::npos) - { - auto eol = text.find ('\n', found + 1); - if (eol != std::string::npos) - { - std::string value = text.substr ( - found + name.length (), - eol - (found + name.length ())); +std::string CmdEdit::findValue(const std::string& text, const std::string& name) { + auto found = text.find(name); + if (found != std::string::npos) { + auto eol = text.find('\n', found + 1); + if (eol != std::string::npos) { + std::string value = text.substr(found + name.length(), eol - (found + name.length())); - return Lexer::trim (value, "\t "); + return Lexer::trim(value, "\t "); } } @@ -134,47 +123,34 @@ std::string CmdEdit::findValue ( } //////////////////////////////////////////////////////////////////////////////// -std::string CmdEdit::findMultilineValue ( - const std::string& text, - const std::string& startMarker, - const std::string& endMarker) -{ - auto start = text.find (startMarker); - if (start != std::string::npos) - { - auto end = text.find (endMarker, start); - if (end != std::string::npos) - { - std::string value = text.substr (start + startMarker.length (), - end - (start + startMarker.length ())); - return Lexer::trim (value, "\\\t "); +std::string CmdEdit::findMultilineValue(const std::string& text, const std::string& startMarker, + const std::string& endMarker) { + auto start = text.find(startMarker); + if (start != std::string::npos) { + auto end = text.find(endMarker, start); + if (end != std::string::npos) { + std::string value = + text.substr(start + startMarker.length(), end - (start + startMarker.length())); + return Lexer::trim(value, "\\\t "); } } return ""; } //////////////////////////////////////////////////////////////////////////////// -std::vector CmdEdit::findValues ( - const std::string& text, - const std::string& name) -{ - std::vector results; +std::vector CmdEdit::findValues(const std::string& text, const std::string& name) { + std::vector results; std::string::size_type found = 0; - while (found != std::string::npos) - { - found = text.find (name, found + 1); - if (found != std::string::npos) - { - auto eol = text.find ('\n', found + 1); - if (eol != std::string::npos) - { - auto value = text.substr ( - found + name.length (), - eol - (found + name.length ())); + while (found != std::string::npos) { + found = text.find(name, found + 1); + if (found != std::string::npos) { + auto eol = text.find('\n', found + 1); + if (eol != std::string::npos) { + auto value = text.substr(found + name.length(), eol - (found + name.length())); found = eol - 1; - results.push_back (Lexer::trim (value, "\t ")); + results.push_back(Lexer::trim(value, "\t ")); } } } @@ -183,35 +159,26 @@ std::vector CmdEdit::findValues ( } //////////////////////////////////////////////////////////////////////////////// -std::string CmdEdit::formatDate ( - Task& task, - const std::string& attribute, - const std::string& dateformat) -{ - auto value = task.get (attribute); - if (value.length ()) - value = Datetime (value).toString (dateformat); +std::string CmdEdit::formatDate(Task& task, const std::string& attribute, + const std::string& dateformat) { + auto value = task.get(attribute); + if (value.length()) value = Datetime(value).toString(dateformat); return value; } //////////////////////////////////////////////////////////////////////////////// -std::string CmdEdit::formatDuration ( - Task& task, - const std::string& attribute) -{ - auto value = task.get (attribute); - if (value.length ()) - value = Duration (value).formatISO (); +std::string CmdEdit::formatDuration(Task& task, const std::string& attribute) { + auto value = task.get(attribute); + if (value.length()) value = Duration(value).formatISO(); return value; } //////////////////////////////////////////////////////////////////////////////// -std::string CmdEdit::formatTask (Task task, const std::string& dateformat) -{ +std::string CmdEdit::formatTask(Task task, const std::string& dateformat) { std::stringstream before; - auto verbose = Context::getContext ().verbose ("edit"); + auto verbose = Context::getContext().verbose("edit"); if (verbose) before << "# The 'task edit' command allows you to modify all aspects of a task\n" @@ -232,408 +199,321 @@ std::string CmdEdit::formatTask (Task task, const std::string& dateformat) before << "# Name Editable details\n" << "# ----------------- ----------------------------------------------------\n" - << "# ID: " << task.id << '\n' - << "# UUID: " << task.get ("uuid") << '\n' - << "# Status: " << Lexer::ucFirst (Task::statusToText (task.getStatus ())) << '\n' - << "# Mask: " << task.get ("mask") << '\n' - << "# iMask: " << task.get ("imask") << '\n' - << " Project: " << task.get ("project") << '\n'; + << "# ID: " << task.id << '\n' + << "# UUID: " << task.get("uuid") << '\n' + << "# Status: " << Lexer::ucFirst(Task::statusToText(task.getStatus())) << '\n' + << "# Mask: " << task.get("mask") << '\n' + << "# iMask: " << task.get("imask") << '\n' + << " Project: " << task.get("project") << '\n'; + + if (verbose) before << "# Separate the tags with spaces, like this: tag1 tag2\n"; + + before << " Tags: " << join(" ", task.getTags()) << '\n' + << " Description: " << task.get("description") << '\n' + << " Created: " << formatDate(task, "entry", dateformat) << '\n' + << " Started: " << formatDate(task, "start", dateformat) << '\n' + << " Ended: " << formatDate(task, "end", dateformat) << '\n' + << " Scheduled: " << formatDate(task, "scheduled", dateformat) << '\n' + << " Due: " << formatDate(task, "due", dateformat) << '\n' + << " Until: " << formatDate(task, "until", dateformat) << '\n' + << " Recur: " << task.get("recur") << '\n' + << " Wait until: " << formatDate(task, "wait", dateformat) << '\n' + << "# Modified: " << formatDate(task, "modified", dateformat) << '\n' + << " Parent: " << task.get("parent") << '\n'; if (verbose) - before << "# Separate the tags with spaces, like this: tag1 tag2\n"; + before + << "# Annotations look like this: -- and there can be any number of them.\n" + "# The ' -- ' separator between the date and text field should not be removed.\n" + "# Multiline annotations need to be indented up to (" + << ANNOTATION_EDIT_MARKER.length() - 1 + << " spaces).\n" + "# A \"blank slot\" for adding an annotation follows for your convenience.\n"; - before << " Tags: " << join (" ", task.getTags ()) << '\n' - << " Description: " << task.get ("description") << '\n' - << " Created: " << formatDate (task, "entry", dateformat) << '\n' - << " Started: " << formatDate (task, "start", dateformat) << '\n' - << " Ended: " << formatDate (task, "end", dateformat) << '\n' - << " Scheduled: " << formatDate (task, "scheduled", dateformat) << '\n' - << " Due: " << formatDate (task, "due", dateformat) << '\n' - << " Until: " << formatDate (task, "until", dateformat) << '\n' - << " Recur: " << task.get ("recur") << '\n' - << " Wait until: " << formatDate (task, "wait", dateformat) << '\n' - << "# Modified: " << formatDate (task, "modified", dateformat) << '\n' - << " Parent: " << task.get ("parent") << '\n'; - - if (verbose) - before << "# Annotations look like this: -- and there can be any number of them.\n" - "# The ' -- ' separator between the date and text field should not be removed.\n" - "# Multiline annotations need to be indented up to (" << ANNOTATION_EDIT_MARKER.length () - 1 << " spaces).\n" - "# A \"blank slot\" for adding an annotation follows for your convenience.\n"; - - for (auto& anno : task.getAnnotations ()) - { - Datetime dt (strtoll (anno.first.substr (11).c_str (), nullptr, 10)); - before << " Annotation: " << dt.toString (dateformat) - << " -- " << str_replace (anno.second, "\n", ANNOTATION_EDIT_MARKER) << '\n'; + for (auto& anno : task.getAnnotations()) { + Datetime dt(strtoll(anno.first.substr(11).c_str(), nullptr, 10)); + before << " Annotation: " << dt.toString(dateformat) << " -- " + << str_replace(anno.second, "\n", ANNOTATION_EDIT_MARKER) << '\n'; } Datetime now; - before << " Annotation: " << now.toString (dateformat) << " -- \n"; + before << " Annotation: " << now.toString(dateformat) << " -- \n"; // Add dependencies here. - auto dependencies = task.getDependencyUUIDs (); + auto dependencies = task.getDependencyUUIDs(); std::stringstream allDeps; - for (unsigned int i = 0; i < dependencies.size (); ++i) - { - if (i) - allDeps << ","; + for (unsigned int i = 0; i < dependencies.size(); ++i) { + if (i) allDeps << ","; Task t; - Context::getContext ().tdb2.get (dependencies[i], t); - if (t.getStatus () == Task::pending || - t.getStatus () == Task::waiting) + Context::getContext().tdb2.get(dependencies[i], t); + if (t.getStatus() == Task::pending || t.getStatus() == Task::waiting) allDeps << t.id; else allDeps << dependencies[i]; } if (verbose) - before << "# Dependencies should be a comma-separated list of task IDs/UUIDs or ID ranges, with no spaces.\n"; + before << "# Dependencies should be a comma-separated list of task IDs/UUIDs or ID ranges, " + "with no spaces.\n"; - before << " Dependencies: " << allDeps.str () << '\n'; + before << " Dependencies: " << allDeps.str() << '\n'; // UDAs - std::vector udas; - for (auto& col : Context::getContext ().columns) - if (Context::getContext ().config.get ("uda." + col.first + ".type") != "") - udas.push_back (col.first); + std::vector udas; + for (auto& col : Context::getContext().columns) + if (Context::getContext().config.get("uda." + col.first + ".type") != "") + udas.push_back(col.first); - if (udas.size ()) - { + if (udas.size()) { before << "# User Defined Attributes\n"; - std::sort (udas.begin (), udas.end ()); - for (auto& uda : udas) - { - int pad = 13 - uda.length (); + std::sort(udas.begin(), udas.end()); + for (auto& uda : udas) { + int pad = 13 - uda.length(); std::string padding = ""; - if (pad > 0) - padding = std::string (pad, ' '); + if (pad > 0) padding = std::string(pad, ' '); - std::string type = Context::getContext ().config.get ("uda." + uda + ".type"); - if (type == "string" || type == "numeric") - { - auto value = task.get (uda); - if (type == "string") - value = json::encode (value); + std::string type = Context::getContext().config.get("uda." + uda + ".type"); + if (type == "string" || type == "numeric") { + auto value = task.get(uda); + if (type == "string") value = json::encode(value); before << " UDA " << uda << ": " << padding << value << '\n'; - } - else if (type == "date") - before << " UDA " << uda << ": " << padding << formatDate (task, uda, dateformat) << '\n'; + } else if (type == "date") + before << " UDA " << uda << ": " << padding << formatDate(task, uda, dateformat) << '\n'; else if (type == "duration") - before << " UDA " << uda << ": " << padding << formatDuration (task, uda) << '\n'; + before << " UDA " << uda << ": " << padding << formatDuration(task, uda) << '\n'; } } // UDA orphans - auto orphans = task.getUDAOrphans (); - if (orphans.size ()) - { + auto orphans = task.getUDAOrphans(); + if (orphans.size()) { before << "# User Defined Attribute Orphans\n"; - std::sort (orphans.begin (), orphans.end ()); - for (auto& orphan : orphans) - { - int pad = 6 - orphan.length (); + std::sort(orphans.begin(), orphans.end()); + for (auto& orphan : orphans) { + int pad = 6 - orphan.length(); std::string padding = ""; - if (pad > 0) - padding = std::string (pad, ' '); + if (pad > 0) padding = std::string(pad, ' '); - before << " UDA Orphan " << orphan << ": " << padding << task.get (orphan) << '\n'; + before << " UDA Orphan " << orphan << ": " << padding << task.get(orphan) << '\n'; } } before << "# End\n"; - return before.str (); + return before.str(); } //////////////////////////////////////////////////////////////////////////////// -void CmdEdit::parseTask (Task& task, const std::string& after, const std::string& dateformat) -{ +void CmdEdit::parseTask(Task& task, const std::string& after, const std::string& dateformat) { // project - auto value = findValue (after, "\n Project:"); - if (task.get ("project") != value) - { - if (value != "") - { - Context::getContext ().footnote ("Project modified."); - task.set ("project", value); - } - else - { - Context::getContext ().footnote ("Project deleted."); - task.remove ("project"); + auto value = findValue(after, "\n Project:"); + if (task.get("project") != value) { + if (value != "") { + Context::getContext().footnote("Project modified."); + task.set("project", value); + } else { + Context::getContext().footnote("Project deleted."); + task.remove("project"); } } // tags - value = findValue (after, "\n Tags:"); - task.remove ("tags"); - task.setTags (split (value, ' ')); + value = findValue(after, "\n Tags:"); + task.remove("tags"); + task.setTags(split(value, ' ')); // description. - value = findMultilineValue (after, "\n Description:", "\n Created:"); - if (task.get ("description") != value) - { - if (value != "") - { - Context::getContext ().footnote ("Description modified."); - task.set ("description", value); - } - else - throw std::string ("Cannot remove description."); + value = findMultilineValue(after, "\n Description:", "\n Created:"); + if (task.get("description") != value) { + if (value != "") { + Context::getContext().footnote("Description modified."); + task.set("description", value); + } else + throw std::string("Cannot remove description."); } // entry - value = findValue (after, "\n Created:"); - if (value != "") - { - if (value != formatDate (task, "entry", dateformat)) - { - Context::getContext ().footnote ("Creation date modified."); - task.set ("entry", Datetime (value, dateformat).toEpochString ()); + value = findValue(after, "\n Created:"); + if (value != "") { + if (value != formatDate(task, "entry", dateformat)) { + Context::getContext().footnote("Creation date modified."); + task.set("entry", Datetime(value, dateformat).toEpochString()); } - } - else - throw std::string ("Cannot remove creation date."); + } else + throw std::string("Cannot remove creation date."); // start - value = findValue (after, "\n Started:"); - if (value != "") - { - if (task.get ("start") != "") - { - if (value != formatDate (task, "start", dateformat)) - { - Context::getContext ().footnote (STRING_EDIT_START_MOD); - task.set ("start", Datetime (value, dateformat).toEpochString ()); + value = findValue(after, "\n Started:"); + if (value != "") { + if (task.get("start") != "") { + if (value != formatDate(task, "start", dateformat)) { + Context::getContext().footnote(STRING_EDIT_START_MOD); + task.set("start", Datetime(value, dateformat).toEpochString()); } + } else { + Context::getContext().footnote(STRING_EDIT_START_MOD); + task.set("start", Datetime(value, dateformat).toEpochString()); } - else - { - Context::getContext ().footnote (STRING_EDIT_START_MOD); - task.set ("start", Datetime (value, dateformat).toEpochString ()); - } - } - else - { - if (task.get ("start") != "") - { - Context::getContext ().footnote ("Start date removed."); - task.remove ("start"); + } else { + if (task.get("start") != "") { + Context::getContext().footnote("Start date removed."); + task.remove("start"); } } // end - value = findValue (after, "\n Ended:"); - if (value != "") - { - if (task.get ("end") != "") - { - if (value != formatDate (task, "end", dateformat)) - { - Context::getContext ().footnote ("End date modified."); - task.set ("end", Datetime (value, dateformat).toEpochString ()); + value = findValue(after, "\n Ended:"); + if (value != "") { + if (task.get("end") != "") { + if (value != formatDate(task, "end", dateformat)) { + Context::getContext().footnote("End date modified."); + task.set("end", Datetime(value, dateformat).toEpochString()); } - } - else if (task.getStatus () != Task::deleted) - throw std::string ("Cannot set a done date on a pending task."); - } - else - { - if (task.get ("end") != "") - { - Context::getContext ().footnote ("End date removed."); - task.setStatus (Task::pending); - task.remove ("end"); + } else if (task.getStatus() != Task::deleted) + throw std::string("Cannot set a done date on a pending task."); + } else { + if (task.get("end") != "") { + Context::getContext().footnote("End date removed."); + task.setStatus(Task::pending); + task.remove("end"); } } // scheduled - value = findValue (after, "\n Scheduled:"); - if (value != "") - { - if (task.get ("scheduled") != "") - { - if (value != formatDate (task, "scheduled", dateformat)) - { - Context::getContext ().footnote (STRING_EDIT_SCHED_MOD); - task.set ("scheduled", Datetime (value, dateformat).toEpochString ()); + value = findValue(after, "\n Scheduled:"); + if (value != "") { + if (task.get("scheduled") != "") { + if (value != formatDate(task, "scheduled", dateformat)) { + Context::getContext().footnote(STRING_EDIT_SCHED_MOD); + task.set("scheduled", Datetime(value, dateformat).toEpochString()); } + } else { + Context::getContext().footnote(STRING_EDIT_SCHED_MOD); + task.set("scheduled", Datetime(value, dateformat).toEpochString()); } - else - { - Context::getContext ().footnote (STRING_EDIT_SCHED_MOD); - task.set ("scheduled", Datetime (value, dateformat).toEpochString ()); - } - } - else - { - if (task.get ("scheduled") != "") - { - Context::getContext ().footnote ("Scheduled date removed."); - task.remove ("scheduled"); + } else { + if (task.get("scheduled") != "") { + Context::getContext().footnote("Scheduled date removed."); + task.remove("scheduled"); } } // due - value = findValue (after, "\n Due:"); - if (value != "") - { - if (task.get ("due") != "") - { - if (value != formatDate (task, "due", dateformat)) - { - Context::getContext ().footnote (STRING_EDIT_DUE_MOD); - task.set ("due", Datetime (value, dateformat).toEpochString ()); + value = findValue(after, "\n Due:"); + if (value != "") { + if (task.get("due") != "") { + if (value != formatDate(task, "due", dateformat)) { + Context::getContext().footnote(STRING_EDIT_DUE_MOD); + task.set("due", Datetime(value, dateformat).toEpochString()); } + } else { + Context::getContext().footnote(STRING_EDIT_DUE_MOD); + task.set("due", Datetime(value, dateformat).toEpochString()); } - else - { - Context::getContext ().footnote (STRING_EDIT_DUE_MOD); - task.set ("due", Datetime (value, dateformat).toEpochString ()); - } - } - else - { - if (task.get ("due") != "") - { - if (task.getStatus () == Task::recurring || - task.get ("parent") != "") - { - Context::getContext ().footnote ("Cannot remove a due date from a recurring task."); - } - else - { - Context::getContext ().footnote ("Due date removed."); - task.remove ("due"); + } else { + if (task.get("due") != "") { + if (task.getStatus() == Task::recurring || task.get("parent") != "") { + Context::getContext().footnote("Cannot remove a due date from a recurring task."); + } else { + Context::getContext().footnote("Due date removed."); + task.remove("due"); } } } // until - value = findValue (after, "\n Until:"); - if (value != "") - { - if (task.get ("until") != "") - { - if (value != formatDate (task, "until", dateformat)) - { - Context::getContext ().footnote (STRING_EDIT_UNTIL_MOD); - task.set ("until", Datetime (value, dateformat).toEpochString ()); + value = findValue(after, "\n Until:"); + if (value != "") { + if (task.get("until") != "") { + if (value != formatDate(task, "until", dateformat)) { + Context::getContext().footnote(STRING_EDIT_UNTIL_MOD); + task.set("until", Datetime(value, dateformat).toEpochString()); } + } else { + Context::getContext().footnote(STRING_EDIT_UNTIL_MOD); + task.set("until", Datetime(value, dateformat).toEpochString()); } - else - { - Context::getContext ().footnote (STRING_EDIT_UNTIL_MOD); - task.set ("until", Datetime (value, dateformat).toEpochString ()); - } - } - else - { - if (task.get ("until") != "") - { - Context::getContext ().footnote ("Until date removed."); - task.remove ("until"); + } else { + if (task.get("until") != "") { + Context::getContext().footnote("Until date removed."); + task.remove("until"); } } // recur - value = findValue (after, "\n Recur:"); - if (value != task.get ("recur")) - { - if (value != "") - { + value = findValue(after, "\n Recur:"); + if (value != task.get("recur")) { + if (value != "") { Duration p; std::string::size_type idx = 0; - if (p.parse (value, idx)) - { - Context::getContext ().footnote ("Recurrence modified."); - if (task.get ("due") != "") - { - task.set ("recur", value); - task.setStatus (Task::recurring); - } - else - throw std::string ("A recurring task must have a due date."); - } - else - throw std::string ("Not a valid recurrence duration."); - } - else - { - Context::getContext ().footnote ("Recurrence removed."); - task.setStatus (Task::pending); - task.remove ("recur"); - task.remove ("until"); - task.remove ("mask"); - task.remove ("imask"); + if (p.parse(value, idx)) { + Context::getContext().footnote("Recurrence modified."); + if (task.get("due") != "") { + task.set("recur", value); + task.setStatus(Task::recurring); + } else + throw std::string("A recurring task must have a due date."); + } else + throw std::string("Not a valid recurrence duration."); + } else { + Context::getContext().footnote("Recurrence removed."); + task.setStatus(Task::pending); + task.remove("recur"); + task.remove("until"); + task.remove("mask"); + task.remove("imask"); } } // wait - value = findValue (after, "\n Wait until:"); - if (value != "") - { - if (task.get ("wait") != "") - { - if (value != formatDate (task, "wait", dateformat)) - { - Context::getContext ().footnote (STRING_EDIT_WAIT_MOD); - task.set ("wait", Datetime (value, dateformat).toEpochString ()); - task.setStatus (Task::waiting); + value = findValue(after, "\n Wait until:"); + if (value != "") { + if (task.get("wait") != "") { + if (value != formatDate(task, "wait", dateformat)) { + Context::getContext().footnote(STRING_EDIT_WAIT_MOD); + task.set("wait", Datetime(value, dateformat).toEpochString()); + task.setStatus(Task::waiting); } + } else { + Context::getContext().footnote(STRING_EDIT_WAIT_MOD); + task.set("wait", Datetime(value, dateformat).toEpochString()); + task.setStatus(Task::waiting); } - else - { - Context::getContext ().footnote (STRING_EDIT_WAIT_MOD); - task.set ("wait", Datetime (value, dateformat).toEpochString ()); - task.setStatus (Task::waiting); - } - } - else - { - if (task.get ("wait") != "") - { - Context::getContext ().footnote ("Wait date removed."); - task.remove ("wait"); - task.setStatus (Task::pending); + } else { + if (task.get("wait") != "") { + Context::getContext().footnote("Wait date removed."); + task.remove("wait"); + task.setStatus(Task::pending); } } // parent - value = findValue (after, "\n Parent:"); - if (value != task.get ("parent")) - { - if (value != "") - { - Context::getContext ().footnote ("Parent UUID modified."); - task.set ("parent", value); - } - else - { - Context::getContext ().footnote ("Parent UUID removed."); - task.remove ("parent"); + value = findValue(after, "\n Parent:"); + if (value != task.get("parent")) { + if (value != "") { + Context::getContext().footnote("Parent UUID modified."); + task.set("parent", value); + } else { + Context::getContext().footnote("Parent UUID removed."); + task.remove("parent"); } } // Annotations - std::map annotations; + std::map annotations; std::string::size_type found = 0; - while ((found = after.find ("\n Annotation:", found)) != std::string::npos) - { + while ((found = after.find("\n Annotation:", found)) != std::string::npos) { found += 14; // Length of "\n Annotation:". auto eol = found; - while ((eol = after.find ('\n', ++eol)) != std::string::npos) - if (after.substr (eol, ANNOTATION_EDIT_MARKER.length ()) != ANNOTATION_EDIT_MARKER) - break; + while ((eol = after.find('\n', ++eol)) != std::string::npos) + if (after.substr(eol, ANNOTATION_EDIT_MARKER.length()) != ANNOTATION_EDIT_MARKER) break; - if (eol != std::string::npos) - { - auto value = Lexer::trim (str_replace (after.substr (found, eol - found), ANNOTATION_EDIT_MARKER, "\n"), "\t "); - auto gap = value.find (" -- "); - if (gap != std::string::npos) - { + if (eol != std::string::npos) { + auto value = Lexer::trim( + str_replace(after.substr(found, eol - found), ANNOTATION_EDIT_MARKER, "\n"), "\t "); + auto gap = value.find(" -- "); + if (gap != std::string::npos) { // TODO keeping the initial dates even if dateformat approximates them // is complex as finding the correspondence between each original line // and edited line may be impossible (bug #705). It would be simpler if @@ -641,228 +521,191 @@ void CmdEdit::parseTask (Task& task, const std::string& after, const std::string // for each line: if the annotation is the same, then it is copied; if // the annotation is modified, then its original date may be kept; and // if there is no corresponding id, then a new unique date is created). - Datetime when (value.substr (0, gap), dateformat); + Datetime when(value.substr(0, gap), dateformat); // If the map already contains an annotation for a given timestamp // we need to increment until we find an unused key - int timestamp = (int) when.toEpoch (); + int timestamp = (int)when.toEpoch(); std::stringstream name; - do - { - name.str (""); // Clear + do { + name.str(""); // Clear name << "annotation_" << timestamp; timestamp++; - } - while (annotations.find (name.str ()) != annotations.end ()); + } while (annotations.find(name.str()) != annotations.end()); - auto text = Lexer::trim (value.substr (gap + 4), "\t "); - annotations.emplace (name.str (), text); + auto text = Lexer::trim(value.substr(gap + 4), "\t "); + annotations.emplace(name.str(), text); } } } - task.setAnnotations (annotations); + task.setAnnotations(annotations); // Dependencies - value = findValue (after, "\n Dependencies:"); - auto dependencies = split (value, ','); + value = findValue(after, "\n Dependencies:"); + auto dependencies = split(value, ','); - for (auto& dep : task.getDependencyUUIDs ()) - task.removeDependency (dep); - for (auto& dep : dependencies) - { - if (dep.length () >= 7) - task.addDependency (dep); + for (auto& dep : task.getDependencyUUIDs()) task.removeDependency(dep); + for (auto& dep : dependencies) { + if (dep.length() >= 7) + task.addDependency(dep); else - task.addDependency ((int) strtol (dep.c_str (), nullptr, 10)); + task.addDependency((int)strtol(dep.c_str(), nullptr, 10)); } // UDAs - for (auto& col : Context::getContext ().columns) - { - auto type = Context::getContext ().config.get ("uda." + col.first + ".type"); - if (type != "") - { - auto value = findValue (after, "\n UDA " + col.first + ":"); - if (type == "string") - value = json::decode (value); - if ((task.get (col.first) != value) && (type != "date" || - (task.get (col.first) != Datetime (value, dateformat).toEpochString ())) && - (type != "duration" || - (task.get (col.first) != Duration (value).toString ()))) - { - if (value != "") - { - Context::getContext ().footnote (format ("UDA {1} modified.", col.first)); + for (auto& col : Context::getContext().columns) { + auto type = Context::getContext().config.get("uda." + col.first + ".type"); + if (type != "") { + auto value = findValue(after, "\n UDA " + col.first + ":"); + if (type == "string") value = json::decode(value); + if ((task.get(col.first) != value) && + (type != "date" || + (task.get(col.first) != Datetime(value, dateformat).toEpochString())) && + (type != "duration" || (task.get(col.first) != Duration(value).toString()))) { + if (value != "") { + Context::getContext().footnote(format("UDA {1} modified.", col.first)); - if (type == "string") - { - task.set (col.first, value); - } - else if (type == "numeric") - { - Pig pig (value); + if (type == "string") { + task.set(col.first, value); + } else if (type == "numeric") { + Pig pig(value); double d; - if (pig.getNumber (d) && - pig.eos ()) - task.set (col.first, value); + if (pig.getNumber(d) && pig.eos()) + task.set(col.first, value); else - throw format ("The value '{1}' is not a valid numeric value.", value); + throw format("The value '{1}' is not a valid numeric value.", value); + } else if (type == "date") { + task.set(col.first, Datetime(value, dateformat).toEpochString()); + } else if (type == "duration") { + task.set(col.first, Duration(value).toTime_t()); } - else if (type == "date") - { - task.set (col.first, Datetime (value, dateformat).toEpochString ()); - } - else if (type == "duration") - { - task.set (col.first, Duration (value).toTime_t ()); - } - } - else - { - Context::getContext ().footnote (format ("UDA {1} deleted.", col.first)); - task.remove (col.first); + } else { + Context::getContext().footnote(format("UDA {1} deleted.", col.first)); + task.remove(col.first); } } } } // UDA orphans - for (auto& orphan : findValues (after, "\n UDA Orphan ")) - { - auto colon = orphan.find (':'); - if (colon != std::string::npos) - { - std::string name = Lexer::trim (orphan.substr (0, colon), "\t "); - std::string value = Lexer::trim (orphan.substr (colon + 1), "\t "); + for (auto& orphan : findValues(after, "\n UDA Orphan ")) { + auto colon = orphan.find(':'); + if (colon != std::string::npos) { + std::string name = Lexer::trim(orphan.substr(0, colon), "\t "); + std::string value = Lexer::trim(orphan.substr(colon + 1), "\t "); if (value != "") - task.set (name, value); + task.set(name, value); else - task.remove (name); + task.remove(name); } } } //////////////////////////////////////////////////////////////////////////////// -CmdEdit::editResult CmdEdit::editFile (Task& task) -{ +CmdEdit::editResult CmdEdit::editFile(Task& task) { // Check for file permissions. - Directory location (Context::getContext ().config.get ("data.location")); - if (! location.writable ()) - throw std::string ("Your data.location directory is not writable."); + Directory location(Context::getContext().config.get("data.location")); + if (!location.writable()) throw std::string("Your data.location directory is not writable."); // Create a temp file name in data.location. std::stringstream file; - file << "task." << task.get ("uuid").substr (0, 8) << ".task"; + file << "task." << task.get("uuid").substr(0, 8) << ".task"; // Determine the output date format, which uses a hierarchy of definitions. // rc.dateformat.edit // rc.dateformat - auto dateformat = Context::getContext ().config.get ("dateformat.edit"); - if (dateformat == "") - dateformat = Context::getContext ().config.get ("dateformat"); + auto dateformat = Context::getContext().config.get("dateformat.edit"); + if (dateformat == "") dateformat = Context::getContext().config.get("dateformat"); // Change directory for the editor - auto current_dir = Directory::cwd (); - int ignored = chdir (location._data.c_str ()); - ++ignored; // Keep compiler quiet. + auto current_dir = Directory::cwd(); + int ignored = chdir(location._data.c_str()); + ++ignored; // Keep compiler quiet. // Check if the file already exists, if so, bail out - Path filepath = Path (file.str ()); - if (filepath.exists ()) - throw std::string ("Task is already being edited."); + Path filepath = Path(file.str()); + if (filepath.exists()) throw std::string("Task is already being edited."); // Format the contents, T -> text, write to a file. - auto before = formatTask (task, dateformat); + auto before = formatTask(task, dateformat); auto before_orig = before; - File::write (file.str (), before); + File::write(file.str(), before); // Determine correct editor: .taskrc:editor > $VISUAL > $EDITOR > vi - auto editor = Context::getContext ().config.get ("editor"); - char* peditor = getenv ("VISUAL"); - if (editor == "" && peditor) editor = std::string (peditor); - peditor = getenv ("EDITOR"); - if (editor == "" && peditor) editor = std::string (peditor); + auto editor = Context::getContext().config.get("editor"); + char* peditor = getenv("VISUAL"); + if (editor == "" && peditor) editor = std::string(peditor); + peditor = getenv("EDITOR"); + if (editor == "" && peditor) editor = std::string(peditor); if (editor == "") editor = "vi"; // Complete the command line. editor += ' '; - editor += '"' + file.str () + '"'; + editor += '"' + file.str() + '"'; ARE_THESE_REALLY_HARMFUL: - bool changes = false; // No changes made. + bool changes = false; // No changes made. // Launch the editor. - std::cout << format ("Launching '{1}' now...\n", editor); - int exitcode = system (editor.c_str ()); + std::cout << format("Launching '{1}' now...\n", editor); + int exitcode = system(editor.c_str()); auto captured_errno = errno; if (0 == exitcode) std::cout << "Editing complete.\n"; - else - { - std::cout << format ("Editing failed with exit code {1}.\n", exitcode); - if (-1 == exitcode) - std::cout << std::strerror (captured_errno) << '\n'; - File::remove (file.str ()); + else { + std::cout << format("Editing failed with exit code {1}.\n", exitcode); + if (-1 == exitcode) std::cout << std::strerror(captured_errno) << '\n'; + File::remove(file.str()); return CmdEdit::editResult::error; } // Slurp file. std::string after; - File::read (file.str (), after); + File::read(file.str(), after); // Update task based on what can be parsed back out of the file, but only // if changes were made. - if (before_orig != after) - { + if (before_orig != after) { std::cout << "Edits were detected.\n"; std::string problem = ""; auto oops = false; - try - { - parseTask (task, after, dateformat); + try { + parseTask(task, after, dateformat); } - catch (const std::string& e) - { + catch (const std::string& e) { problem = e; oops = true; } - if (oops) - { + if (oops) { std::cerr << "Error: " << problem << '\n'; - File::remove (file.str()); + File::remove(file.str()); - if (confirm ("Taskwarrior couldn't handle your edits. Would you like to try again?")) - { + if (confirm("Taskwarrior couldn't handle your edits. Would you like to try again?")) { // Preserve the edits. before = after; - File::write (file.str (), before); + File::write(file.str(), before); goto ARE_THESE_REALLY_HARMFUL; } - } - else + } else changes = true; - } - else - { + } else { std::cout << "No edits were detected.\n"; changes = false; } // Cleanup. - File::remove (file.str ()); - ignored = chdir (current_dir.c_str ()); - return changes - ? CmdEdit::editResult::changes - : CmdEdit::editResult::nochanges; + File::remove(file.str()); + ignored = chdir(current_dir.c_str()); + return changes ? CmdEdit::editResult::changes : CmdEdit::editResult::nochanges; } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/commands/CmdEdit.h b/src/commands/CmdEdit.h index 9d2272594..2d5fbd3d7 100644 --- a/src/commands/CmdEdit.h +++ b/src/commands/CmdEdit.h @@ -27,26 +27,26 @@ #ifndef INCLUDED_CMDEDIT #define INCLUDED_CMDEDIT -#include #include #include -class CmdEdit : public Command -{ -public: - CmdEdit (); - int execute (std::string&); +#include -private: - std::string findValue (const std::string&, const std::string&); - std::string findMultilineValue (const std::string&, const std::string&, const std::string&); - std::vector findValues (const std::string&, const std::string&); - std::string formatDate (Task&, const std::string&, const std::string&); - std::string formatDuration (Task&, const std::string&); - std::string formatTask (Task, const std::string&); - void parseTask (Task&, const std::string&, const std::string&); +class CmdEdit : public Command { + public: + CmdEdit(); + int execute(std::string&); + + private: + std::string findValue(const std::string&, const std::string&); + std::string findMultilineValue(const std::string&, const std::string&, const std::string&); + std::vector findValues(const std::string&, const std::string&); + std::string formatDate(Task&, const std::string&, const std::string&); + std::string formatDuration(Task&, const std::string&); + std::string formatTask(Task, const std::string&); + void parseTask(Task&, const std::string&, const std::string&); enum class editResult { error, changes, nochanges }; - editResult editFile (Task&); + editResult editFile(Task&); static const std::string ANNOTATION_EDIT_MARKER; }; diff --git a/src/commands/CmdExec.cpp b/src/commands/CmdExec.cpp index 3c200d6ba..3391f0447 100644 --- a/src/commands/CmdExec.cpp +++ b/src/commands/CmdExec.cpp @@ -28,38 +28,34 @@ // cmake.h include header must come first #include -#include #include #include +#include //////////////////////////////////////////////////////////////////////////////// -CmdExec::CmdExec () -{ - _keyword = "execute"; - _usage = "task execute "; - _description = "Executes external commands and scripts"; - _read_only = true; - _displays_id = false; - _needs_gc = false; - _uses_context = false; - _accepts_filter = false; +CmdExec::CmdExec() { + _keyword = "execute"; + _usage = "task execute "; + _description = "Executes external commands and scripts"; + _read_only = true; + _displays_id = false; + _needs_gc = false; + _uses_context = false; + _accepts_filter = false; _accepts_modifications = false; _accepts_miscellaneous = true; - _category = Command::Category::misc; + _category = Command::Category::misc; } //////////////////////////////////////////////////////////////////////////////// -int CmdExec::execute (std::string&) -{ - std::string command = join (" ", Context::getContext ().cli2.getWords ()); +int CmdExec::execute(std::string&) { + std::string command = join(" ", Context::getContext().cli2.getWords()); - if (command.empty()) - { - Context::getContext ().error ("Cannot execute an empty command."); + if (command.empty()) { + Context::getContext().error("Cannot execute an empty command."); return 1; - } - else - return system (command.c_str ()); + } else + return system(command.c_str()); } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/commands/CmdExec.h b/src/commands/CmdExec.h index 82e0d16ec..4847ebff7 100644 --- a/src/commands/CmdExec.h +++ b/src/commands/CmdExec.h @@ -27,14 +27,14 @@ #ifndef INCLUDED_CMDEXEC #define INCLUDED_CMDEXEC -#include #include -class CmdExec : public Command -{ -public: - CmdExec (); - int execute (std::string&); +#include + +class CmdExec : public Command { + public: + CmdExec(); + int execute(std::string&); }; #endif diff --git a/src/commands/CmdExport.cpp b/src/commands/CmdExport.cpp index dcbd26206..a51f6428e 100644 --- a/src/commands/CmdExport.cpp +++ b/src/commands/CmdExport.cpp @@ -31,100 +31,86 @@ #include #include #include -#include -#include #include +#include //////////////////////////////////////////////////////////////////////////////// -CmdExport::CmdExport () -{ - _keyword = "export"; - _usage = "task export []"; - _description = "Exports tasks in JSON format"; - _read_only = true; - _displays_id = true; - _needs_gc = true; - _uses_context = false; - _accepts_filter = true; +CmdExport::CmdExport() { + _keyword = "export"; + _usage = "task export []"; + _description = "Exports tasks in JSON format"; + _read_only = true; + _displays_id = true; + _needs_gc = true; + _uses_context = false; + _accepts_filter = true; _accepts_modifications = false; _accepts_miscellaneous = true; - _category = Command::Category::migration; + _category = Command::Category::migration; } //////////////////////////////////////////////////////////////////////////////// -int CmdExport::execute (std::string& output) -{ +int CmdExport::execute(std::string& output) { int rc = 0; - auto words = Context::getContext ().cli2.getWords (); + auto words = Context::getContext().cli2.getWords(); std::string selectedReport = ""; - if (words.size () == 1) - { + if (words.size() == 1) { // Find the report matching the prompt - for (auto& command : Context::getContext ().commands) - { - if (command.second->category () == Command::Category::report && - closeEnough(command.second->keyword (), words[0])) - { - selectedReport = command.second->keyword (); + for (auto& command : Context::getContext().commands) { + if (command.second->category() == Command::Category::report && + closeEnough(command.second->keyword(), words[0])) { + selectedReport = command.second->keyword(); break; } } - if (selectedReport.empty ()) { - throw format("Unable to find report that matches '{1}'.", words[0]); + if (selectedReport.empty()) { + throw format("Unable to find report that matches '{1}'.", words[0]); } } - auto reportSort = Context::getContext ().config.get ("report." + selectedReport + ".sort"); - auto reportFilter = Context::getContext ().config.get ("report." + selectedReport + ".filter"); + auto reportSort = Context::getContext().config.get("report." + selectedReport + ".sort"); + auto reportFilter = Context::getContext().config.get("report." + selectedReport + ".filter"); - auto sortOrder = split (reportSort, ','); - if (sortOrder.size () != 0 && - sortOrder[0] != "none") { - validateSortColumns (sortOrder); - } + auto sortOrder = split(reportSort, ','); + if (sortOrder.size() != 0 && sortOrder[0] != "none") { + validateSortColumns(sortOrder); + } // Add the report filter to any existing filter. - if (reportFilter != "") - Context::getContext ().cli2.addFilter (reportFilter); + if (reportFilter != "") Context::getContext().cli2.addFilter(reportFilter); // Make sure reccurent tasks are generated. - handleUntil (); - handleRecurrence (); + handleUntil(); + handleRecurrence(); // Apply filter. Filter filter; - std::vector filtered; - filter.subset (filtered); + std::vector filtered; + filter.subset(filtered); - std::vector sequence; - if (sortOrder.size () && - sortOrder[0] == "none") - { + std::vector sequence; + if (sortOrder.size() && sortOrder[0] == "none") { // Assemble a sequence vector that represents the tasks listed in // Context::getContext ().cli2._uuid_ranges, in the order in which they appear. This // equates to no sorting, just a specified order. - sortOrder.clear (); - for (auto& i : Context::getContext ().cli2._uuid_list) - for (unsigned int t = 0; t < filtered.size (); ++t) - if (filtered[t].get ("uuid") == i) - sequence.push_back (t); - } - else - { + sortOrder.clear(); + for (auto& i : Context::getContext().cli2._uuid_list) + for (unsigned int t = 0; t < filtered.size(); ++t) + if (filtered[t].get("uuid") == i) sequence.push_back(t); + } else { // sort_tasks requires the order array initially be identity - for (unsigned int i = 0; i < filtered.size (); ++i) - sequence.push_back (i); + for (unsigned int i = 0; i < filtered.size(); ++i) sequence.push_back(i); // if no sort order, sort by id - if (!sortOrder.size ()) { + if (!sortOrder.size()) { reportSort = "id,uuid"; } // Sort the tasks. - sort_tasks (filtered, sequence, reportSort); + sort_tasks(filtered, sequence, reportSort); } // Export == render. @@ -133,48 +119,39 @@ int CmdExport::execute (std::string& output) // Obey 'limit:N'. int rows = 0; int lines = 0; - Context::getContext ().getLimits (rows, lines); + Context::getContext().getLimits(rows, lines); int limit = (rows > lines ? rows : lines); // Is output contained within a JSON array? - bool json_array = Context::getContext ().config.getBoolean ("json.array"); + bool json_array = Context::getContext().config.getBoolean("json.array"); // Compose output. - if (json_array) - output += "[\n"; + if (json_array) output += "[\n"; int counter = 0; - for (auto& t : sequence) - { + for (auto& t : sequence) { auto task = filtered[t]; - if (counter) - { - if (json_array) - output += ','; + if (counter) { + if (json_array) output += ','; output += '\n'; } - output += task.composeJSON (true); + output += task.composeJSON(true); ++counter; - if (limit && counter >= limit) - break; + if (limit && counter >= limit) break; } - if (filtered.size ()) - output += '\n'; + if (filtered.size()) output += '\n'; - if (json_array) - output += "]\n"; + if (json_array) output += "]\n"; - Context::getContext ().time_render_us += timer.total_us (); + Context::getContext().time_render_us += timer.total_us(); return rc; } //////////////////////////////////////////////////////////////////////////////// -void CmdExport::validateSortColumns (std::vector & columns) -{ - for (auto& col : columns) - legacySortColumnMap (col); +void CmdExport::validateSortColumns(std::vector& columns) { + for (auto& col : columns) legacySortColumnMap(col); } diff --git a/src/commands/CmdExport.h b/src/commands/CmdExport.h index 24eb252c3..db3faee90 100644 --- a/src/commands/CmdExport.h +++ b/src/commands/CmdExport.h @@ -27,16 +27,17 @@ #ifndef INCLUDED_CMDEXPORT #define INCLUDED_CMDEXPORT -#include #include -class CmdExport : public Command -{ -public: - CmdExport (); - int execute (std::string&); -private: - void validateSortColumns (std::vector &); +#include + +class CmdExport : public Command { + public: + CmdExport(); + int execute(std::string&); + + private: + void validateSortColumns(std::vector&); }; #endif diff --git a/src/commands/CmdGet.cpp b/src/commands/CmdGet.cpp index 0c2eb7173..c6114cc28 100644 --- a/src/commands/CmdGet.cpp +++ b/src/commands/CmdGet.cpp @@ -28,27 +28,26 @@ // cmake.h include header must come first #include -#include #include #include +#include +#include #include #include -#include //////////////////////////////////////////////////////////////////////////////// -CmdGet::CmdGet () -{ - _keyword = "_get"; - _usage = "task _get [ ...]"; - _description = "DOM Accessor"; - _read_only = true; - _displays_id = false; - _needs_gc = false; - _uses_context = false; - _accepts_filter = false; +CmdGet::CmdGet() { + _keyword = "_get"; + _usage = "task _get [ ...]"; + _description = "DOM Accessor"; + _read_only = true; + _displays_id = false; + _needs_gc = false; + _uses_context = false; + _accepts_filter = false; _accepts_modifications = false; _accepts_miscellaneous = true; - _category = Command::Category::internal; + _category = Command::Category::internal; } //////////////////////////////////////////////////////////////////////////////// @@ -57,39 +56,32 @@ CmdGet::CmdGet () // // It is an error to specify no DOM references. // It is not an error for a DOM reference to resolve to a blank value. -int CmdGet::execute (std::string& output) -{ - std::vector results; - for (auto& arg : Context::getContext ().cli2._args) - { - switch (arg._lextype) - { - case Lexer::Type::dom: - { +int CmdGet::execute(std::string& output) { + std::vector results; + for (auto& arg : Context::getContext().cli2._args) { + switch (arg._lextype) { + case Lexer::Type::dom: { Variant result; - if (getDOM (arg.attribute ("raw"), NULL, result)) - results.emplace_back (result); + if (getDOM(arg.attribute("raw"), NULL, result)) + results.emplace_back(result); else - results.emplace_back (""); - } - break; + results.emplace_back(""); + } break; - // Look for non-refs to complain about. - case Lexer::Type::word: - case Lexer::Type::identifier: - if (! arg.hasTag ("BINARY") && - ! arg.hasTag ("CMD")) - throw format ("'{1}' is not a DOM reference.", arg.attribute ("raw")); + // Look for non-refs to complain about. + case Lexer::Type::word: + case Lexer::Type::identifier: + if (!arg.hasTag("BINARY") && !arg.hasTag("CMD")) + throw format("'{1}' is not a DOM reference.", arg.attribute("raw")); - default: - break; + default: + break; } } - if (results.size () == 0) - throw std::string ("No DOM reference specified."); + if (results.size() == 0) throw std::string("No DOM reference specified."); - output = join (" ", results); + output = join(" ", results); output += '\n'; return 0; } diff --git a/src/commands/CmdGet.h b/src/commands/CmdGet.h index 68fe81f84..18f651a0c 100644 --- a/src/commands/CmdGet.h +++ b/src/commands/CmdGet.h @@ -27,14 +27,14 @@ #ifndef INCLUDED_CMDGET #define INCLUDED_CMDGET -#include #include -class CmdGet : public Command -{ -public: - CmdGet (); - int execute (std::string&); +#include + +class CmdGet : public Command { + public: + CmdGet(); + int execute(std::string&); }; #endif diff --git a/src/commands/CmdHelp.cpp b/src/commands/CmdHelp.cpp index 72c2ea51a..033b12789 100644 --- a/src/commands/CmdHelp.cpp +++ b/src/commands/CmdHelp.cpp @@ -28,217 +28,205 @@ // cmake.h include header must come first #include -#include -#include #include -#include +#include #include +#include #include +#include + //////////////////////////////////////////////////////////////////////////////// -CmdHelp::CmdHelp () -{ - _keyword = "help"; - _usage = "task help ['usage']"; - _description = "Displays this usage help text"; - _read_only = true; - _displays_id = false; - _needs_gc = false; - _uses_context = false; - _accepts_filter = false; +CmdHelp::CmdHelp() { + _keyword = "help"; + _usage = "task help ['usage']"; + _description = "Displays this usage help text"; + _read_only = true; + _displays_id = false; + _needs_gc = false; + _uses_context = false; + _accepts_filter = false; _accepts_modifications = false; _accepts_miscellaneous = true; - _category = Command::Category::misc; + _category = Command::Category::misc; } //////////////////////////////////////////////////////////////////////////////// -int CmdHelp::execute (std::string& output) -{ - auto words = Context::getContext ().cli2.getWords (); - if (words.size () == 1 && closeEnough ("usage", words[0])) - output = '\n' - + composeUsage () - + '\n'; +int CmdHelp::execute(std::string& output) { + auto words = Context::getContext().cli2.getWords(); + if (words.size() == 1 && closeEnough("usage", words[0])) + output = '\n' + composeUsage() + '\n'; else - output = '\n' - + composeUsage () - + '\n' - + "Documentation for Taskwarrior can be found using 'man task', 'man taskrc', 'man " - "task-color', 'man task-sync' or at https://taskwarrior.org\n" - "\n" - "The general form of commands is:\n" - " task [] []\n" - "\n" - "The consists of zero or more restrictions on which tasks to select, " - "such as:\n" - " task \n" - " task 28 \n" - " task +weekend \n" - " task project:Home due.before:today \n" - " task ebeeab00-ccf8-464b-8b58-f7f2d606edfb \n" - "\n" - "By default, filter elements are combined with an implicit 'and' operator, but " - "'or' and 'xor' may also be used, provided parentheses are included:\n" - " task '(/[Cc]at|[Dd]og/ or /[0-9]+/)' \n" - "\n" - "A filter may target specific tasks using ID or UUID numbers. To specify " - "multiple tasks use one of these forms:\n" - " task 1,2,3 delete\n" - " task 1-3 info\n" - " task 1,2-5,19 modify pri:H\n" - " task 4-7 ebeeab00-ccf8-464b-8b58-f7f2d606edfb info\n" - "\n" - "The consist of zero or more changes to apply to the selected tasks, " - "such as:\n" - " task project:Home\n" - " task +weekend +garden due:tomorrow\n" - " task Description/annotation text\n" - " task /from/to/ <- replace first match\n" - " task /from/to/g <- replace all matches\n" - "\n" - "Tags are arbitrary words, any quantity:\n" - " +tag The + means add the tag\n" - " -tag The - means remove the tag\n" - "\n" - "Built-in attributes are:\n" - " description: Task description text\n" - " status: Status of task - pending, completed, deleted, waiting\n" - " project: Project name\n" - " priority: Priority\n" - " due: Due date\n" - " recur: Recurrence frequency\n" - " until: Expiration date of a task\n" - " limit: Desired number of rows in report, or 'page'\n" - " wait: Date until task becomes pending\n" - " entry: Date task was created\n" - " end: Date task was completed/deleted\n" - " start: Date task was started\n" - " scheduled: Date task is scheduled to start\n" - " modified: Date task was last modified\n" - " depends: Other tasks that this task depends upon\n" - "\n" - "Attribute modifiers make filters more precise. Supported modifiers are:\n" - "\n" - " Modifiers Example Equivalent Meaning\n" - " ---------------- ----------------- ------------------- -------------------------\n" - " due:today due = today Fuzzy match\n" - " not due.not:today due != today Fuzzy non-match\n" - " before, below due.before:today due < today Exact date comparison\n" - " after, above due.after:today due >= tomorrow Exact date comparison\n" - " none project.none: project == '' Empty\n" - " any project.any: project !== '' Not empty\n" - " is, equals project.is:x project == x Exact match\n" - " isnt project.isnt:x project !== x Exact non-match\n" - " has, contains desc.has:Hello desc ~ Hello Pattern match\n" - " hasnt, desc.hasnt:Hello desc !~ Hello Pattern non-match\n" - " startswith, left desc.left:Hel desc ~ '^Hel' Beginning match\n" - " endswith, right desc.right:llo desc ~ 'llo$' End match\n" - " word desc.word:Hello desc ~ '\\bHello\\b' Boundaried word match\n" - " noword desc.noword:Hello desc !~ '\\bHello\\b' Boundaried word non-match\n" - "\n" - "Alternately algebraic expressions support:\n" - " and or xor Logical operators\n" - " < <= = != >= > Relational operators\n" - " ( ) Precedence\n" - "\n" - " task due.before:eom priority.not:L list\n" - " task '(due < eom and priority != L)' list\n" - "\n" - "The default .taskrc file can be overridden with:\n" - " task ... rc: ...\n" - " task ... rc:~/.alt_taskrc ...\n" - "\n" - "The values in .taskrc (or alternate) can be overridden with:\n" - " task ... rc.= ...\n" - " task rc.color=off list\n" - "\n" - "Any command or attribute name may be abbreviated if still unique:\n" - " task list project:Home\n" - " task li pro:Home\n" - "\n" - "Some task descriptions need to be escaped because of the shell:\n" - " task add \"quoted ' quote\"\n" - " task add escaped \\' quote\n" - "\n" - "The argument -- tells Taskwarrior to treat all other args as description, even " - "if they would otherwise be attributes or tags:\n" - " task add -- project:Home needs scheduling\n" - "\n" - "Many characters have special meaning to the shell, including:\n" - " $ ! ' \" ( ) ; \\ ` * ? { } [ ] < > | & % # ~\n" - "\n"; + output = + '\n' + composeUsage() + '\n' + + "Documentation for Taskwarrior can be found using 'man task', 'man taskrc', 'man " + "task-color', 'man task-sync' or at https://taskwarrior.org\n" + "\n" + "The general form of commands is:\n" + " task [] []\n" + "\n" + "The consists of zero or more restrictions on which tasks to select, " + "such as:\n" + " task \n" + " task 28 \n" + " task +weekend \n" + " task project:Home due.before:today \n" + " task ebeeab00-ccf8-464b-8b58-f7f2d606edfb \n" + "\n" + "By default, filter elements are combined with an implicit 'and' operator, but " + "'or' and 'xor' may also be used, provided parentheses are included:\n" + " task '(/[Cc]at|[Dd]og/ or /[0-9]+/)' \n" + "\n" + "A filter may target specific tasks using ID or UUID numbers. To specify " + "multiple tasks use one of these forms:\n" + " task 1,2,3 delete\n" + " task 1-3 info\n" + " task 1,2-5,19 modify pri:H\n" + " task 4-7 ebeeab00-ccf8-464b-8b58-f7f2d606edfb info\n" + "\n" + "The consist of zero or more changes to apply to the selected tasks, " + "such as:\n" + " task project:Home\n" + " task +weekend +garden due:tomorrow\n" + " task Description/annotation text\n" + " task /from/to/ <- replace first match\n" + " task /from/to/g <- replace all matches\n" + "\n" + "Tags are arbitrary words, any quantity:\n" + " +tag The + means add the tag\n" + " -tag The - means remove the tag\n" + "\n" + "Built-in attributes are:\n" + " description: Task description text\n" + " status: Status of task - pending, completed, deleted, waiting\n" + " project: Project name\n" + " priority: Priority\n" + " due: Due date\n" + " recur: Recurrence frequency\n" + " until: Expiration date of a task\n" + " limit: Desired number of rows in report, or 'page'\n" + " wait: Date until task becomes pending\n" + " entry: Date task was created\n" + " end: Date task was completed/deleted\n" + " start: Date task was started\n" + " scheduled: Date task is scheduled to start\n" + " modified: Date task was last modified\n" + " depends: Other tasks that this task depends upon\n" + "\n" + "Attribute modifiers make filters more precise. Supported modifiers are:\n" + "\n" + " Modifiers Example Equivalent Meaning\n" + " ---------------- ----------------- ------------------- -------------------------\n" + " due:today due = today Fuzzy match\n" + " not due.not:today due != today Fuzzy non-match\n" + " before, below due.before:today due < today Exact date comparison\n" + " after, above due.after:today due >= tomorrow Exact date comparison\n" + " none project.none: project == '' Empty\n" + " any project.any: project !== '' Not empty\n" + " is, equals project.is:x project == x Exact match\n" + " isnt project.isnt:x project !== x Exact non-match\n" + " has, contains desc.has:Hello desc ~ Hello Pattern match\n" + " hasnt, desc.hasnt:Hello desc !~ Hello Pattern non-match\n" + " startswith, left desc.left:Hel desc ~ '^Hel' Beginning match\n" + " endswith, right desc.right:llo desc ~ 'llo$' End match\n" + " word desc.word:Hello desc ~ '\\bHello\\b' Boundaried word match\n" + " noword desc.noword:Hello desc !~ '\\bHello\\b' Boundaried word non-match\n" + "\n" + "Alternately algebraic expressions support:\n" + " and or xor Logical operators\n" + " < <= = != >= > Relational operators\n" + " ( ) Precedence\n" + "\n" + " task due.before:eom priority.not:L list\n" + " task '(due < eom and priority != L)' list\n" + "\n" + "The default .taskrc file can be overridden with:\n" + " task ... rc: ...\n" + " task ... rc:~/.alt_taskrc ...\n" + "\n" + "The values in .taskrc (or alternate) can be overridden with:\n" + " task ... rc.= ...\n" + " task rc.color=off list\n" + "\n" + "Any command or attribute name may be abbreviated if still unique:\n" + " task list project:Home\n" + " task li pro:Home\n" + "\n" + "Some task descriptions need to be escaped because of the shell:\n" + " task add \"quoted ' quote\"\n" + " task add escaped \\' quote\n" + "\n" + "The argument -- tells Taskwarrior to treat all other args as description, even " + "if they would otherwise be attributes or tags:\n" + " task add -- project:Home needs scheduling\n" + "\n" + "Many characters have special meaning to the shell, including:\n" + " $ ! ' \" ( ) ; \\ ` * ? { } [ ] < > | & % # ~\n" + "\n"; - /* - TODO To be included later, before the 'precedence' line. + /* + TODO To be included later, before the 'precedence' line. - " + - Addition, Subtraktion\n" \ - " ! Negation\n" \ - " ~ !~ Treffer, kein Treffer\n" \ - */ + " + - Addition, Subtraktion\n" \ + " ! Negation\n" \ + " ~ !~ Treffer, kein Treffer\n" \ + */ return 0; } //////////////////////////////////////////////////////////////////////////////// -std::string CmdHelp::composeUsage () const -{ +std::string CmdHelp::composeUsage() const { Table view; - view.width (Context::getContext ().getWidth ()); - view.add (""); - view.add (""); - view.add (""); + view.width(Context::getContext().getWidth()); + view.add(""); + view.add(""); + view.add(""); // Static first row. - auto row = view.addRow (); - view.set (row, 0, "Usage:"); - view.set (row, 1, "task"); - view.set (row, 2, "Runs rc.default.command, if specified."); + auto row = view.addRow(); + view.set(row, 0, "Usage:"); + view.set(row, 1, "task"); + view.set(row, 2, "Runs rc.default.command, if specified."); // Obsolete method of getting a list of all commands. - std::vector all; - for (auto& cmd : Context::getContext ().commands) - all.push_back (cmd.first); + std::vector all; + for (auto& cmd : Context::getContext().commands) all.push_back(cmd.first); // Sort alphabetically by usage. - std::sort (all.begin (), all.end ()); + std::sort(all.begin(), all.end()); // Add the regular commands. - for (auto& name : all) - { - if (name[0] != '_') - { - row = view.addRow (); - view.set (row, 1, Context::getContext ().commands[name]->usage ()); - view.set (row, 2, Context::getContext ().commands[name]->description ()); + for (auto& name : all) { + if (name[0] != '_') { + row = view.addRow(); + view.set(row, 1, Context::getContext().commands[name]->usage()); + view.set(row, 2, Context::getContext().commands[name]->description()); } } // Add the helper commands. - for (auto& name : all) - { - if (name[0] == '_') - { - row = view.addRow (); - view.set (row, 1, Context::getContext ().commands[name]->usage ()); - view.set (row, 2, Context::getContext ().commands[name]->description ()); + for (auto& name : all) { + if (name[0] == '_') { + row = view.addRow(); + view.set(row, 1, Context::getContext().commands[name]->usage()); + view.set(row, 2, Context::getContext().commands[name]->description()); } } // Add the aliases commands. - row = view.addRow (); - view.set (row, 1, " "); + row = view.addRow(); + view.set(row, 1, " "); - for (auto& alias : Context::getContext ().config) - { - if (alias.first.substr (0, 6) == "alias.") - { - row = view.addRow (); - view.set (row, 1, alias.first.substr (6)); - view.set (row, 2, format ("Aliased to '{1}'", alias.second)); + for (auto& alias : Context::getContext().config) { + if (alias.first.substr(0, 6) == "alias.") { + row = view.addRow(); + view.set(row, 1, alias.first.substr(6)); + view.set(row, 2, format("Aliased to '{1}'", alias.second)); } } - return view.render (); + return view.render(); } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/commands/CmdHelp.h b/src/commands/CmdHelp.h index 7b793f6a6..af7e2a84a 100644 --- a/src/commands/CmdHelp.h +++ b/src/commands/CmdHelp.h @@ -27,17 +27,17 @@ #ifndef INCLUDED_CMDHELP #define INCLUDED_CMDHELP -#include #include -class CmdHelp : public Command -{ -public: - CmdHelp (); - int execute (std::string&); +#include -private: - std::string composeUsage () const; +class CmdHelp : public Command { + public: + CmdHelp(); + int execute(std::string&); + + private: + std::string composeUsage() const; }; #endif diff --git a/src/commands/CmdHistory.cpp b/src/commands/CmdHistory.cpp index 5f895b8e8..4449aea13 100644 --- a/src/commands/CmdHistory.cpp +++ b/src/commands/CmdHistory.cpp @@ -28,343 +28,299 @@ // cmake.h include header must come first #include -#include #include +#include #include #include -#include #include +#include #include -#include -#define STRING_CMD_HISTORY_YEAR "Year" -#define STRING_CMD_HISTORY_MONTH "Month" -#define STRING_CMD_HISTORY_DAY "Day" -#define STRING_CMD_HISTORY_ADDED "Added" -#define STRING_CMD_HISTORY_COMP "Completed" -#define STRING_CMD_HISTORY_DEL "Deleted" +#include + +#define STRING_CMD_HISTORY_YEAR "Year" +#define STRING_CMD_HISTORY_MONTH "Month" +#define STRING_CMD_HISTORY_DAY "Day" +#define STRING_CMD_HISTORY_ADDED "Added" +#define STRING_CMD_HISTORY_COMP "Completed" +#define STRING_CMD_HISTORY_DEL "Deleted" //////////////////////////////////////////////////////////////////////////////// -template -CmdHistoryBase::CmdHistoryBase () -{ - _keyword = HistoryStrategy::keyword; - _usage = HistoryStrategy::usage; - _description = HistoryStrategy::description; +template +CmdHistoryBase::CmdHistoryBase() { + _keyword = HistoryStrategy::keyword; + _usage = HistoryStrategy::usage; + _description = HistoryStrategy::description; - _read_only = true; - _displays_id = false; - _needs_gc = false; - _uses_context = true; - _accepts_filter = true; + _read_only = true; + _displays_id = false; + _needs_gc = false; + _uses_context = true; + _accepts_filter = true; _accepts_modifications = false; _accepts_miscellaneous = false; - _category = Command::Category::graphs; + _category = Command::Category::graphs; } //////////////////////////////////////////////////////////////////////////////// -template -void CmdHistoryBase::outputGraphical (std::string& output) -{ - auto widthOfBar = Context::getContext ().getWidth () - HistoryStrategy::labelWidth; +template +void CmdHistoryBase::outputGraphical(std::string& output) { + auto widthOfBar = Context::getContext().getWidth() - HistoryStrategy::labelWidth; // Now build the view. Table view; - setHeaderUnderline (view); - view.width (Context::getContext ().getWidth ()); + setHeaderUnderline(view); + view.width(Context::getContext().getWidth()); - HistoryStrategy::setupTableDates (view); + HistoryStrategy::setupTableDates(view); - view.add ("Number Added/Completed/Deleted", true, false); // Fixed. + view.add("Number Added/Completed/Deleted", true, false); // Fixed. - Color color_add (Context::getContext ().config.get ("color.history.add")); - Color color_done (Context::getContext ().config.get ("color.history.done")); - Color color_delete (Context::getContext ().config.get ("color.history.delete")); - Color label (Context::getContext ().config.get ("color.label")); + Color color_add(Context::getContext().config.get("color.history.add")); + Color color_done(Context::getContext().config.get("color.history.done")); + Color color_delete(Context::getContext().config.get("color.history.delete")); + Color label(Context::getContext().config.get("color.label")); // Determine the longest line, and the longest "added" line. auto maxAddedLine = 0; auto maxRemovedLine = 0; - for (auto& i : groups) - { + for (auto& i : groups) { if (completedGroup[i.first] + deletedGroup[i.first] > maxRemovedLine) maxRemovedLine = completedGroup[i.first] + deletedGroup[i.first]; - if (addedGroup[i.first] > maxAddedLine) - maxAddedLine = addedGroup[i.first]; + if (addedGroup[i.first] > maxAddedLine) maxAddedLine = addedGroup[i.first]; } auto maxLine = maxAddedLine + maxRemovedLine; - if (maxLine > 0) - { + if (maxLine > 0) { unsigned int leftOffset = (widthOfBar * maxAddedLine) / maxLine; time_t priorTime = 0; auto row = 0; - for (auto& i : groups) - { - row = view.addRow (); + for (auto& i : groups) { + row = view.addRow(); - HistoryStrategy::insertRowDate (view, row, i.first, priorTime); + HistoryStrategy::insertRowDate(view, row, i.first, priorTime); priorTime = i.first; - unsigned int addedBar = (widthOfBar * addedGroup[i.first]) / maxLine; + unsigned int addedBar = (widthOfBar * addedGroup[i.first]) / maxLine; unsigned int completedBar = (widthOfBar * completedGroup[i.first]) / maxLine; - unsigned int deletedBar = (widthOfBar * deletedGroup[i.first]) / maxLine; + unsigned int deletedBar = (widthOfBar * deletedGroup[i.first]) / maxLine; std::string bar; - if (Context::getContext ().color ()) - { + if (Context::getContext().color()) { std::string aBar; - if (addedGroup[i.first]) - { - aBar = format (addedGroup[i.first]); - while (aBar.length () < addedBar) - aBar = ' ' + aBar; + if (addedGroup[i.first]) { + aBar = format(addedGroup[i.first]); + while (aBar.length() < addedBar) aBar = ' ' + aBar; } std::string cBar; - if (completedGroup[i.first]) - { - cBar = format (completedGroup[i.first]); - while (cBar.length () < completedBar) - cBar = ' ' + cBar; + if (completedGroup[i.first]) { + cBar = format(completedGroup[i.first]); + while (cBar.length() < completedBar) cBar = ' ' + cBar; } std::string dBar; - if (deletedGroup[i.first]) - { - dBar = format (deletedGroup[i.first]); - while (dBar.length () < deletedBar) - dBar = ' ' + dBar; + if (deletedGroup[i.first]) { + dBar = format(deletedGroup[i.first]); + while (dBar.length() < deletedBar) dBar = ' ' + dBar; } - bar += std::string (leftOffset - aBar.length (), ' '); - bar += color_add.colorize (aBar); - bar += color_done.colorize (cBar); - bar += color_delete.colorize (dBar); - } - else - { - std::string aBar; while (aBar.length () < addedBar) aBar += '+'; - std::string cBar; while (cBar.length () < completedBar) cBar += 'X'; - std::string dBar; while (dBar.length () < deletedBar) dBar += '-'; + bar += std::string(leftOffset - aBar.length(), ' '); + bar += color_add.colorize(aBar); + bar += color_done.colorize(cBar); + bar += color_delete.colorize(dBar); + } else { + std::string aBar; + while (aBar.length() < addedBar) aBar += '+'; + std::string cBar; + while (cBar.length() < completedBar) cBar += 'X'; + std::string dBar; + while (dBar.length() < deletedBar) dBar += '-'; - bar += std::string (leftOffset - aBar.length (), ' '); + bar += std::string(leftOffset - aBar.length(), ' '); bar += aBar + cBar + dBar; } - view.set (row, HistoryStrategy::dateFieldCount + 0, bar); + view.set(row, HistoryStrategy::dateFieldCount + 0, bar); } } std::stringstream out; - if (view.rows ()) - { - out << optionalBlankLine () - << view.render () - << '\n'; + if (view.rows()) { + out << optionalBlankLine() << view.render() << '\n'; - if (Context::getContext ().color ()) - out << format ("Legend: {1}, {2}, {3}", - color_add.colorize (STRING_CMD_HISTORY_ADDED), - color_done.colorize (STRING_CMD_HISTORY_COMP), - color_delete.colorize (STRING_CMD_HISTORY_DEL)) - << optionalBlankLine () - << '\n'; + if (Context::getContext().color()) + out << format("Legend: {1}, {2}, {3}", color_add.colorize(STRING_CMD_HISTORY_ADDED), + color_done.colorize(STRING_CMD_HISTORY_COMP), + color_delete.colorize(STRING_CMD_HISTORY_DEL)) + << optionalBlankLine() << '\n'; else out << "Legend: + Added, X Completed, - Deleted\n"; - } - else - { - Context::getContext ().footnote ("No tasks."); + } else { + Context::getContext().footnote("No tasks."); rc = 1; } - output = out.str (); + output = out.str(); } //////////////////////////////////////////////////////////////////////////////// -template -void CmdHistoryBase::outputTabular (std::string& output) -{ +template +void CmdHistoryBase::outputTabular(std::string& output) { Table view; - setHeaderUnderline (view); - view.width (Context::getContext ().getWidth ()); + setHeaderUnderline(view); + view.width(Context::getContext().getWidth()); - HistoryStrategy::setupTableDates (view); + HistoryStrategy::setupTableDates(view); - view.add (STRING_CMD_HISTORY_ADDED, false); - view.add (STRING_CMD_HISTORY_COMP, false); - view.add (STRING_CMD_HISTORY_DEL, false); - view.add ("Net", false); + view.add(STRING_CMD_HISTORY_ADDED, false); + view.add(STRING_CMD_HISTORY_COMP, false); + view.add(STRING_CMD_HISTORY_DEL, false); + view.add("Net", false); - auto totalAdded = 0; + auto totalAdded = 0; auto totalCompleted = 0; - auto totalDeleted = 0; + auto totalDeleted = 0; auto row = 0; time_t lastTime = 0; - for (auto& i : groups) - { - row = view.addRow (); + for (auto& i : groups) { + row = view.addRow(); - totalAdded += addedGroup [i.first]; - totalCompleted += completedGroup [i.first]; - totalDeleted += deletedGroup [i.first]; + totalAdded += addedGroup[i.first]; + totalCompleted += completedGroup[i.first]; + totalDeleted += deletedGroup[i.first]; - HistoryStrategy::insertRowDate (view, row, i.first, lastTime); + HistoryStrategy::insertRowDate(view, row, i.first, lastTime); lastTime = i.first; auto net = 0; - if (addedGroup.find (i.first) != addedGroup.end ()) - { - view.set (row, HistoryStrategy::dateFieldCount + 0, addedGroup[i.first]); - net +=addedGroup[i.first]; + if (addedGroup.find(i.first) != addedGroup.end()) { + view.set(row, HistoryStrategy::dateFieldCount + 0, addedGroup[i.first]); + net += addedGroup[i.first]; } - if (completedGroup.find (i.first) != completedGroup.end ()) - { - view.set (row, HistoryStrategy::dateFieldCount + 1, completedGroup[i.first]); + if (completedGroup.find(i.first) != completedGroup.end()) { + view.set(row, HistoryStrategy::dateFieldCount + 1, completedGroup[i.first]); net -= completedGroup[i.first]; } - if (deletedGroup.find (i.first) != deletedGroup.end ()) - { - view.set (row, HistoryStrategy::dateFieldCount + 2, deletedGroup[i.first]); + if (deletedGroup.find(i.first) != deletedGroup.end()) { + view.set(row, HistoryStrategy::dateFieldCount + 2, deletedGroup[i.first]); net -= deletedGroup[i.first]; } Color net_color; - if (Context::getContext ().color () && net) - net_color = net > 0 - ? Color (Color::red) - : Color (Color::green); + if (Context::getContext().color() && net) + net_color = net > 0 ? Color(Color::red) : Color(Color::green); - view.set (row, HistoryStrategy::dateFieldCount + 3, net, net_color); + view.set(row, HistoryStrategy::dateFieldCount + 3, net, net_color); } - if (view.rows ()) - { + if (view.rows()) { + row = view.addRow(); + view.set(row, 1, " "); row = view.addRow(); - view.set (row, 1, " "); - row = view.addRow (); Color row_color; - if (Context::getContext ().color ()) - row_color = Color (Color::nocolor, Color::nocolor, false, true, false); + if (Context::getContext().color()) + row_color = Color(Color::nocolor, Color::nocolor, false, true, false); - view.set (row, HistoryStrategy::dateFieldCount - 1, "Average", row_color); - view.set (row, HistoryStrategy::dateFieldCount + 0, totalAdded / (view.rows () - 2), row_color); - view.set (row, HistoryStrategy::dateFieldCount + 1, totalCompleted / (view.rows () - 2), row_color); - view.set (row, HistoryStrategy::dateFieldCount + 2, totalDeleted / (view.rows () - 2), row_color); - view.set (row, HistoryStrategy::dateFieldCount + 3, (totalAdded - totalCompleted - totalDeleted) / (view.rows () - 2), row_color); + view.set(row, HistoryStrategy::dateFieldCount - 1, "Average", row_color); + view.set(row, HistoryStrategy::dateFieldCount + 0, totalAdded / (view.rows() - 2), row_color); + view.set(row, HistoryStrategy::dateFieldCount + 1, totalCompleted / (view.rows() - 2), + row_color); + view.set(row, HistoryStrategy::dateFieldCount + 2, totalDeleted / (view.rows() - 2), row_color); + view.set(row, HistoryStrategy::dateFieldCount + 3, + (totalAdded - totalCompleted - totalDeleted) / (view.rows() - 2), row_color); } std::stringstream out; - if (view.rows ()) - out << optionalBlankLine () - << view.render () - << '\n'; - else - { - Context::getContext ().footnote ("No tasks."); + if (view.rows()) + out << optionalBlankLine() << view.render() << '\n'; + else { + Context::getContext().footnote("No tasks."); rc = 1; } - output = out.str (); + output = out.str(); } ////////////////////////////////////////////////////////////////////////////i -class MonthlyHistoryStrategy -{ -public: - static Datetime getRelevantDate (const Datetime& dt) - { - return dt.startOfMonth (); +class MonthlyHistoryStrategy { + public: + static Datetime getRelevantDate(const Datetime& dt) { return dt.startOfMonth(); } + + static void setupTableDates(Table& view) { + view.add(STRING_CMD_HISTORY_YEAR, true); + view.add(STRING_CMD_HISTORY_MONTH, true); } - static void setupTableDates (Table& view) - { - view.add (STRING_CMD_HISTORY_YEAR, true); - view.add (STRING_CMD_HISTORY_MONTH, true); - } - - static void insertRowDate ( - Table& view, - int row, - time_t rowTime, - time_t lastTime) - { - Datetime dt (rowTime); + static void insertRowDate(Table& view, int row, time_t rowTime, time_t lastTime) { + Datetime dt(rowTime); int m, d, y; - dt.toYMD (y, m, d); + dt.toYMD(y, m, d); - Datetime last_dt (lastTime); + Datetime last_dt(lastTime); int last_m, last_d, last_y; - last_dt.toYMD (last_y, last_m, last_d); + last_dt.toYMD(last_y, last_m, last_d); - if (y != last_y) - view.set (row, 0, y); + if (y != last_y) view.set(row, 0, y); - view.set (row, 1, Datetime::monthName (m)); + view.set(row, 1, Datetime::monthName(m)); } - static constexpr const char* keyword = "history.monthly"; - static constexpr const char* usage = "task history.monthly"; - static constexpr const char* description = "Shows a report of task history, by month"; + static constexpr const char* keyword = "history.monthly"; + static constexpr const char* usage = "task history.monthly"; + static constexpr const char* description = "Shows a report of task history, by month"; static constexpr unsigned int dateFieldCount = 2; - static constexpr bool graphical = false; - static constexpr unsigned int labelWidth = 0; // unused. + static constexpr bool graphical = false; + static constexpr unsigned int labelWidth = 0; // unused. }; //////////////////////////////////////////////////////////////////////////////// -template -int CmdHistoryBase::execute (std::string& output) -{ +template +int CmdHistoryBase::execute(std::string& output) { rc = 0; // TODO is this necessary? - groups.clear (); - addedGroup.clear (); - deletedGroup.clear (); - completedGroup.clear (); + groups.clear(); + addedGroup.clear(); + deletedGroup.clear(); + completedGroup.clear(); // Apply filter. - handleUntil (); - handleRecurrence (); + handleUntil(); + handleRecurrence(); Filter filter; - std::vector filtered; - filter.subset (filtered); + std::vector filtered; + filter.subset(filtered); - for (auto& task : filtered) - { - Datetime entry (task.get_date ("entry")); + for (auto& task : filtered) { + Datetime entry(task.get_date("entry")); Datetime end; - if (task.has ("end")) - end = Datetime (task.get_date ("end")); + if (task.has("end")) end = Datetime(task.get_date("end")); - auto epoch = HistoryStrategy::getRelevantDate (entry).toEpoch (); + auto epoch = HistoryStrategy::getRelevantDate(entry).toEpoch(); groups[epoch] = 0; // Every task has an entry date, but exclude templates. - if (task.getStatus () != Task::recurring) - ++addedGroup[epoch]; + if (task.getStatus() != Task::recurring) ++addedGroup[epoch]; // All deleted tasks have an end date. - if (task.getStatus () == Task::deleted) - { - epoch = HistoryStrategy::getRelevantDate (end).toEpoch (); + if (task.getStatus() == Task::deleted) { + epoch = HistoryStrategy::getRelevantDate(end).toEpoch(); groups[epoch] = 0; ++deletedGroup[epoch]; } // All completed tasks have an end date. - else if (task.getStatus () == Task::completed) - { - epoch = HistoryStrategy::getRelevantDate (end).toEpoch (); + else if (task.getStatus() == Task::completed) { + epoch = HistoryStrategy::getRelevantDate(end).toEpoch(); groups[epoch] = 0; ++completedGroup[epoch]; } @@ -372,338 +328,251 @@ int CmdHistoryBase::execute (std::string& output) // Now build the view. if (HistoryStrategy::graphical) - this->outputGraphical (output); + this->outputGraphical(output); else - this->outputTabular (output); + this->outputTabular(output); return rc; } ////////////////////////////////////////////////////////////////////////////i -class MonthlyGHistoryStrategy -{ -public: - static Datetime getRelevantDate (const Datetime& dt) - { - return dt.startOfMonth (); +class MonthlyGHistoryStrategy { + public: + static Datetime getRelevantDate(const Datetime& dt) { return dt.startOfMonth(); } + + static void setupTableDates(Table& view) { + view.add(STRING_CMD_HISTORY_YEAR, true); + view.add(STRING_CMD_HISTORY_MONTH, true); } - static void setupTableDates (Table& view) - { - view.add (STRING_CMD_HISTORY_YEAR, true); - view.add (STRING_CMD_HISTORY_MONTH, true); - } - - static void insertRowDate ( - Table& view, - int row, - time_t rowTime, - time_t lastTime) - { - Datetime dt (rowTime); + static void insertRowDate(Table& view, int row, time_t rowTime, time_t lastTime) { + Datetime dt(rowTime); int m, d, y; - dt.toYMD (y, m, d); + dt.toYMD(y, m, d); - Datetime last_dt (lastTime); + Datetime last_dt(lastTime); int last_m, last_d, last_y; - last_dt.toYMD (last_y, last_m, last_d); + last_dt.toYMD(last_y, last_m, last_d); - if (y != last_y) - view.set (row, 0, y); + if (y != last_y) view.set(row, 0, y); - view.set (row, 1, Datetime::monthName (m)); + view.set(row, 1, Datetime::monthName(m)); } - static constexpr const char* keyword = "ghistory.monthly"; - static constexpr const char* usage = "task ghistory.monthly"; - static constexpr const char* description = "Shows a graphical report of task history, by month"; + static constexpr const char* keyword = "ghistory.monthly"; + static constexpr const char* usage = "task ghistory.monthly"; + static constexpr const char* description = "Shows a graphical report of task history, by month"; static constexpr unsigned int dateFieldCount = 2; - static constexpr bool graphical = true; - static constexpr unsigned int labelWidth = 15; // length '2017 September ' = 15 + static constexpr bool graphical = true; + static constexpr unsigned int labelWidth = 15; // length '2017 September ' = 15 }; ////////////////////////////////////////////////////////////////////////////i -class AnnualGHistoryStrategy -{ -public: - static Datetime getRelevantDate (const Datetime& dt) - { - return dt.startOfYear (); - } +class AnnualGHistoryStrategy { + public: + static Datetime getRelevantDate(const Datetime& dt) { return dt.startOfYear(); } - static void setupTableDates (Table& view) - { - view.add (STRING_CMD_HISTORY_YEAR, true); - } + static void setupTableDates(Table& view) { view.add(STRING_CMD_HISTORY_YEAR, true); } - static void insertRowDate ( - Table& view, - int row, - time_t rowTime, - time_t lastTime) - { - Datetime dt (rowTime); + static void insertRowDate(Table& view, int row, time_t rowTime, time_t lastTime) { + Datetime dt(rowTime); int m, d, y; - dt.toYMD (y, m, d); + dt.toYMD(y, m, d); - Datetime last_dt (lastTime); + Datetime last_dt(lastTime); int last_m, last_d, last_y; - last_dt.toYMD (last_y, last_m, last_d); + last_dt.toYMD(last_y, last_m, last_d); - if (y != last_y) - view.set (row, 0, y); + if (y != last_y) view.set(row, 0, y); } - static constexpr const char* keyword = "ghistory.annual"; - static constexpr const char* usage = "task ghistory.annual"; - static constexpr const char* description = "Shows a graphical report of task history, by year"; + static constexpr const char* keyword = "ghistory.annual"; + static constexpr const char* usage = "task ghistory.annual"; + static constexpr const char* description = "Shows a graphical report of task history, by year"; static constexpr unsigned int dateFieldCount = 1; - static constexpr bool graphical = true; - static constexpr unsigned int labelWidth = 5; // length '2017 ' = 5 + static constexpr bool graphical = true; + static constexpr unsigned int labelWidth = 5; // length '2017 ' = 5 }; ////////////////////////////////////////////////////////////////////////////i -class AnnualHistoryStrategy -{ -public: - static Datetime getRelevantDate (const Datetime& dt) - { - return dt.startOfYear (); - } +class AnnualHistoryStrategy { + public: + static Datetime getRelevantDate(const Datetime& dt) { return dt.startOfYear(); } - static void setupTableDates (Table& view) - { - view.add (STRING_CMD_HISTORY_YEAR, true); - } + static void setupTableDates(Table& view) { view.add(STRING_CMD_HISTORY_YEAR, true); } - static void insertRowDate ( - Table& view, - int row, - time_t rowTime, - time_t lastTime) - { - Datetime dt (rowTime); + static void insertRowDate(Table& view, int row, time_t rowTime, time_t lastTime) { + Datetime dt(rowTime); int m, d, y; - dt.toYMD (y, m, d); + dt.toYMD(y, m, d); - Datetime last_dt (lastTime); + Datetime last_dt(lastTime); int last_m, last_d, last_y; - last_dt.toYMD (last_y, last_m, last_d); + last_dt.toYMD(last_y, last_m, last_d); - if (y != last_y) - view.set (row, 0, y); + if (y != last_y) view.set(row, 0, y); } - static constexpr const char* keyword = "history.annual"; - static constexpr const char* usage = "task history.annual"; - static constexpr const char* description = "Shows a report of task history, by year"; + static constexpr const char* keyword = "history.annual"; + static constexpr const char* usage = "task history.annual"; + static constexpr const char* description = "Shows a report of task history, by year"; static constexpr unsigned int dateFieldCount = 1; - static constexpr bool graphical = false; - static constexpr unsigned int labelWidth = 0; // unused. + static constexpr bool graphical = false; + static constexpr unsigned int labelWidth = 0; // unused. }; - ////////////////////////////////////////////////////////////////////////////i -class DailyHistoryStrategy -{ -public: - static Datetime getRelevantDate (const Datetime& dt) - { - return dt.startOfDay (); +class DailyHistoryStrategy { + public: + static Datetime getRelevantDate(const Datetime& dt) { return dt.startOfDay(); } + + static void setupTableDates(Table& view) { + view.add(STRING_CMD_HISTORY_YEAR, true); + view.add(STRING_CMD_HISTORY_MONTH, true); + view.add(STRING_CMD_HISTORY_DAY, false); } - static void setupTableDates (Table& view) - { - view.add (STRING_CMD_HISTORY_YEAR, true); - view.add (STRING_CMD_HISTORY_MONTH, true); - view.add (STRING_CMD_HISTORY_DAY, false); - } - - static void insertRowDate ( - Table& view, - int row, - time_t rowTime, - time_t lastTime) - { - Datetime dt (rowTime); + static void insertRowDate(Table& view, int row, time_t rowTime, time_t lastTime) { + Datetime dt(rowTime); int m, d, y; - dt.toYMD (y, m, d); + dt.toYMD(y, m, d); - Datetime last_dt (lastTime); + Datetime last_dt(lastTime); int last_m, last_d, last_y; - last_dt.toYMD (last_y, last_m, last_d); + last_dt.toYMD(last_y, last_m, last_d); bool y_changed = (y != last_y) || (lastTime == 0); bool m_changed = (m != last_m) || (lastTime == 0); - if (y_changed) - view.set (row, 0, y); + if (y_changed) view.set(row, 0, y); - if (y_changed || m_changed) - view.set (row, 1, Datetime::monthName (m)); + if (y_changed || m_changed) view.set(row, 1, Datetime::monthName(m)); - view.set (row, 2, d); + view.set(row, 2, d); } - static constexpr const char* keyword = "history.daily"; - static constexpr const char* usage = "task history.daily"; - static constexpr const char* description = "Shows a report of task history, by day"; + static constexpr const char* keyword = "history.daily"; + static constexpr const char* usage = "task history.daily"; + static constexpr const char* description = "Shows a report of task history, by day"; static constexpr unsigned int dateFieldCount = 3; - static constexpr bool graphical = false; - static constexpr unsigned int labelWidth = 0; // unused. + static constexpr bool graphical = false; + static constexpr unsigned int labelWidth = 0; // unused. }; ////////////////////////////////////////////////////////////////////////////i -class DailyGHistoryStrategy -{ -public: - static Datetime getRelevantDate (const Datetime& dt) - { - return dt.startOfDay (); +class DailyGHistoryStrategy { + public: + static Datetime getRelevantDate(const Datetime& dt) { return dt.startOfDay(); } + + static void setupTableDates(Table& view) { + view.add(STRING_CMD_HISTORY_YEAR, true); + view.add(STRING_CMD_HISTORY_MONTH, true); + view.add(STRING_CMD_HISTORY_DAY, false); } - static void setupTableDates (Table& view) - { - view.add (STRING_CMD_HISTORY_YEAR, true); - view.add (STRING_CMD_HISTORY_MONTH, true); - view.add (STRING_CMD_HISTORY_DAY, false); - } - - static void insertRowDate ( - Table& view, - int row, - time_t rowTime, - time_t lastTime) - { - Datetime dt (rowTime); + static void insertRowDate(Table& view, int row, time_t rowTime, time_t lastTime) { + Datetime dt(rowTime); int m, d, y; - dt.toYMD (y, m, d); + dt.toYMD(y, m, d); - Datetime last_dt (lastTime); + Datetime last_dt(lastTime); int last_m, last_d, last_y; - last_dt.toYMD (last_y, last_m, last_d); + last_dt.toYMD(last_y, last_m, last_d); bool y_changed = (y != last_y) || (lastTime == 0); bool m_changed = (m != last_m) || (lastTime == 0); - if (y_changed) - view.set (row, 0, y); + if (y_changed) view.set(row, 0, y); - if (y_changed || m_changed) - view.set (row, 1, Datetime::monthName (m)); + if (y_changed || m_changed) view.set(row, 1, Datetime::monthName(m)); - view.set (row, 2, d); + view.set(row, 2, d); } - static constexpr const char* keyword = "ghistory.daily"; - static constexpr const char* usage = "task ghistory.daily"; - static constexpr const char* description = "Shows a graphical report of task history, by day"; + static constexpr const char* keyword = "ghistory.daily"; + static constexpr const char* usage = "task ghistory.daily"; + static constexpr const char* description = "Shows a graphical report of task history, by day"; static constexpr unsigned int dateFieldCount = 3; - static constexpr bool graphical = true; - static constexpr unsigned int labelWidth = 19; // length '2017 September Day ' = 19 + static constexpr bool graphical = true; + static constexpr unsigned int labelWidth = 19; // length '2017 September Day ' = 19 }; ////////////////////////////////////////////////////////////////////////////i -class WeeklyHistoryStrategy -{ -public: - static Datetime getRelevantDate (const Datetime& dt) - { - return dt.startOfWeek (); +class WeeklyHistoryStrategy { + public: + static Datetime getRelevantDate(const Datetime& dt) { return dt.startOfWeek(); } + + static void setupTableDates(Table& view) { + view.add(STRING_CMD_HISTORY_YEAR, true); + view.add(STRING_CMD_HISTORY_MONTH, true); + view.add(STRING_CMD_HISTORY_DAY, false); } - static void setupTableDates (Table& view) - { - view.add (STRING_CMD_HISTORY_YEAR, true); - view.add (STRING_CMD_HISTORY_MONTH, true); - view.add (STRING_CMD_HISTORY_DAY, false); - } - - static void insertRowDate ( - Table& view, - int row, - time_t rowTime, - time_t lastTime) - { - Datetime dt (rowTime); + static void insertRowDate(Table& view, int row, time_t rowTime, time_t lastTime) { + Datetime dt(rowTime); int m, d, y; - dt.toYMD (y, m, d); + dt.toYMD(y, m, d); - Datetime last_dt (lastTime); + Datetime last_dt(lastTime); int last_m, last_d, last_y; - last_dt.toYMD (last_y, last_m, last_d); + last_dt.toYMD(last_y, last_m, last_d); bool y_changed = (y != last_y) || (lastTime == 0); bool m_changed = (m != last_m) || (lastTime == 0); - if (y_changed) - view.set (row, 0, y); + if (y_changed) view.set(row, 0, y); - if (y_changed || m_changed) - view.set (row, 1, Datetime::monthName (m)); + if (y_changed || m_changed) view.set(row, 1, Datetime::monthName(m)); - view.set (row, 2, d); + view.set(row, 2, d); } - static constexpr const char* keyword = "history.weekly"; - static constexpr const char* usage = "task history.weekly"; - static constexpr const char* description = "Shows a report of task history, by week"; + static constexpr const char* keyword = "history.weekly"; + static constexpr const char* usage = "task history.weekly"; + static constexpr const char* description = "Shows a report of task history, by week"; static constexpr unsigned int dateFieldCount = 3; - static constexpr bool graphical = false; - static constexpr unsigned int labelWidth = 0; // unused. + static constexpr bool graphical = false; + static constexpr unsigned int labelWidth = 0; // unused. }; ////////////////////////////////////////////////////////////////////////////i -class WeeklyGHistoryStrategy -{ -public: - static Datetime getRelevantDate (const Datetime& dt) - { - return dt.startOfWeek (); +class WeeklyGHistoryStrategy { + public: + static Datetime getRelevantDate(const Datetime& dt) { return dt.startOfWeek(); } + + static void setupTableDates(Table& view) { + view.add(STRING_CMD_HISTORY_YEAR, true); + view.add(STRING_CMD_HISTORY_MONTH, true); + view.add(STRING_CMD_HISTORY_DAY, false); } - static void setupTableDates (Table& view) - { - view.add (STRING_CMD_HISTORY_YEAR, true); - view.add (STRING_CMD_HISTORY_MONTH, true); - view.add (STRING_CMD_HISTORY_DAY, false); - } - - static void insertRowDate ( - Table& view, - int row, - time_t rowTime, - time_t lastTime) - { - Datetime dt (rowTime); + static void insertRowDate(Table& view, int row, time_t rowTime, time_t lastTime) { + Datetime dt(rowTime); int m, d, y; - dt.toYMD (y, m, d); + dt.toYMD(y, m, d); - Datetime last_dt (lastTime); + Datetime last_dt(lastTime); int last_m, last_d, last_y; - last_dt.toYMD (last_y, last_m, last_d); + last_dt.toYMD(last_y, last_m, last_d); bool y_changed = (y != last_y) || (lastTime == 0); bool m_changed = (m != last_m) || (lastTime == 0); - if (y_changed) - view.set (row, 0, y); + if (y_changed) view.set(row, 0, y); - if (y_changed || m_changed) - view.set (row, 1, Datetime::monthName (m)); + if (y_changed || m_changed) view.set(row, 1, Datetime::monthName(m)); - view.set (row, 2, d); + view.set(row, 2, d); } - static constexpr const char* keyword = "ghistory.weekly"; - static constexpr const char* usage = "task ghistory.weekly"; - static constexpr const char* description = "Shows a graphical report of task history, by week"; + static constexpr const char* keyword = "ghistory.weekly"; + static constexpr const char* usage = "task ghistory.weekly"; + static constexpr const char* description = "Shows a graphical report of task history, by week"; static constexpr unsigned int dateFieldCount = 3; - static constexpr bool graphical = true; - static constexpr unsigned int labelWidth = 19; // length '2017 September Day ' = 19 + static constexpr bool graphical = true; + static constexpr unsigned int labelWidth = 19; // length '2017 September Day ' = 19 }; - // Explicit instantiations, avoiding cpp-inclusion or implementation in header template class CmdHistoryBase; template class CmdHistoryBase; diff --git a/src/commands/CmdHistory.h b/src/commands/CmdHistory.h index 311620cf7..f76683442 100644 --- a/src/commands/CmdHistory.h +++ b/src/commands/CmdHistory.h @@ -27,27 +27,27 @@ #ifndef INCLUDED_CMDHISTORY #define INCLUDED_CMDHISTORY -#include #include -#include #include +#include -template -class CmdHistoryBase : public Command -{ -public: - CmdHistoryBase (); - int execute (std::string&); +#include -private: - std::map groups; // Represents any timeinterval with data - std::map addedGroup; // Additions by timeinterval - std::map completedGroup; // Completions by timeinterval - std::map deletedGroup; // Deletions by timeinterval +template +class CmdHistoryBase : public Command { + public: + CmdHistoryBase(); + int execute(std::string&); + + private: + std::map groups; // Represents any timeinterval with data + std::map addedGroup; // Additions by timeinterval + std::map completedGroup; // Completions by timeinterval + std::map deletedGroup; // Deletions by timeinterval int rc; - void outputTabular (std::string&); - void outputGraphical (std::string&); + void outputTabular(std::string&); + void outputGraphical(std::string&); }; // Forward-declare strategies implemented in CmdHistory.cpp @@ -61,13 +61,13 @@ class AnnualHistoryStrategy; class AnnualGHistoryStrategy; // typedef the templates to nice names to be used outside this class -typedef CmdHistoryBase CmdHistoryDaily; -typedef CmdHistoryBase CmdGHistoryDaily; -typedef CmdHistoryBase CmdHistoryWeekly; -typedef CmdHistoryBase CmdGHistoryWeekly; -typedef CmdHistoryBase CmdHistoryMonthly; +typedef CmdHistoryBase CmdHistoryDaily; +typedef CmdHistoryBase CmdGHistoryDaily; +typedef CmdHistoryBase CmdHistoryWeekly; +typedef CmdHistoryBase CmdGHistoryWeekly; +typedef CmdHistoryBase CmdHistoryMonthly; typedef CmdHistoryBase CmdGHistoryMonthly; -typedef CmdHistoryBase CmdHistoryAnnual; -typedef CmdHistoryBase CmdGHistoryAnnual; +typedef CmdHistoryBase CmdHistoryAnnual; +typedef CmdHistoryBase CmdGHistoryAnnual; #endif diff --git a/src/commands/CmdIDs.cpp b/src/commands/CmdIDs.cpp index 3e52aa42b..36024163c 100644 --- a/src/commands/CmdIDs.cpp +++ b/src/commands/CmdIDs.cpp @@ -28,51 +28,49 @@ // cmake.h include header must come first #include -#include -#include #include #include #include #include +#include +#include + std::string zshColonReplacement = ","; //////////////////////////////////////////////////////////////////////////////// -CmdIDs::CmdIDs () -{ - _keyword = "ids"; - _usage = "task ids"; - _description = "Shows the IDs of matching tasks, as a range"; - _read_only = true; - _displays_id = true; - _needs_gc = true; - _uses_context = false; - _accepts_filter = true; +CmdIDs::CmdIDs() { + _keyword = "ids"; + _usage = "task ids"; + _description = "Shows the IDs of matching tasks, as a range"; + _read_only = true; + _displays_id = true; + _needs_gc = true; + _uses_context = false; + _accepts_filter = true; _accepts_modifications = false; _accepts_miscellaneous = false; - _category = Command::Category::metadata; + _category = Command::Category::metadata; } //////////////////////////////////////////////////////////////////////////////// -int CmdIDs::execute (std::string& output) -{ +int CmdIDs::execute(std::string& output) { // Apply filter. - handleUntil (); - handleRecurrence (); + handleUntil(); + handleRecurrence(); Filter filter; - std::vector filtered; - filter.subset (filtered); + std::vector filtered; + filter.subset(filtered); // Find number of matching tasks. - std::vector ids; + std::vector ids; for (auto& task : filtered) - if (task.id) - ids.push_back (task.id); + if (task.id) ids.push_back(task.id); - std::sort (ids.begin (), ids.end ()); - output = compressIds (ids) + '\n'; + std::sort(ids.begin(), ids.end()); + output = compressIds(ids) + '\n'; - Context::getContext ().headers.clear (); + Context::getContext().headers.clear(); return 0; } @@ -88,35 +86,25 @@ int CmdIDs::execute (std::string& output) // // 1,3-4,6-9,11 // -std::string CmdIDs::compressIds (const std::vector & ids) -{ +std::string CmdIDs::compressIds(const std::vector& ids) { std::stringstream result; auto range_start = 0; auto range_end = 0; - for (unsigned int i = 0; i < ids.size (); ++i) - { - if (i + 1 == ids.size ()) - { - if (result.str ().length ()) - result << ' '; + for (unsigned int i = 0; i < ids.size(); ++i) { + if (i + 1 == ids.size()) { + if (result.str().length()) result << ' '; if (range_start < range_end) result << ids[range_start] << '-' << ids[range_end]; else result << ids[range_start]; - } - else - { - if (ids[range_end] + 1 == ids[i + 1]) - { + } else { + if (ids[range_end] + 1 == ids[i + 1]) { ++range_end; - } - else - { - if (result.str ().length ()) - result << ' '; + } else { + if (result.str().length()) result << ' '; if (range_start < range_end) result << ids[range_start] << '-' << ids[range_end]; @@ -128,201 +116,183 @@ std::string CmdIDs::compressIds (const std::vector & ids) } } - return result.str (); + return result.str(); } //////////////////////////////////////////////////////////////////////////////// -CmdCompletionIds::CmdCompletionIds () -{ - _keyword = "_ids"; - _usage = "task _ids"; - _description = "Shows the IDs of matching tasks, in the form of a list"; - _read_only = true; - _displays_id = true; - _needs_gc = true; - _uses_context = false; - _accepts_filter = true; +CmdCompletionIds::CmdCompletionIds() { + _keyword = "_ids"; + _usage = "task _ids"; + _description = "Shows the IDs of matching tasks, in the form of a list"; + _read_only = true; + _displays_id = true; + _needs_gc = true; + _uses_context = false; + _accepts_filter = true; _accepts_modifications = false; _accepts_miscellaneous = false; - _category = Command::Category::internal; + _category = Command::Category::internal; } //////////////////////////////////////////////////////////////////////////////// -int CmdCompletionIds::execute (std::string& output) -{ +int CmdCompletionIds::execute(std::string& output) { // Apply filter. - handleUntil (); - handleRecurrence (); + handleUntil(); + handleRecurrence(); Filter filter; - std::vector filtered; - filter.subset (filtered); + std::vector filtered; + filter.subset(filtered); - std::vector ids; + std::vector ids; for (auto& task : filtered) - if (task.getStatus () != Task::deleted && - task.getStatus () != Task::completed) - ids.push_back (task.id); + if (task.getStatus() != Task::deleted && task.getStatus() != Task::completed) + ids.push_back(task.id); - std::sort (ids.begin (), ids.end ()); - output = join ("\n", ids) + '\n'; + std::sort(ids.begin(), ids.end()); + output = join("\n", ids) + '\n'; - Context::getContext ().headers.clear (); + Context::getContext().headers.clear(); return 0; } //////////////////////////////////////////////////////////////////////////////// -CmdZshCompletionIds::CmdZshCompletionIds () -{ - _keyword = "_zshids"; - _usage = "task _zshids"; - _description = "Shows the IDs and descriptions of matching tasks"; - _read_only = true; - _displays_id = true; - _needs_gc = true; - _uses_context = false; - _accepts_filter = true; +CmdZshCompletionIds::CmdZshCompletionIds() { + _keyword = "_zshids"; + _usage = "task _zshids"; + _description = "Shows the IDs and descriptions of matching tasks"; + _read_only = true; + _displays_id = true; + _needs_gc = true; + _uses_context = false; + _accepts_filter = true; _accepts_modifications = false; _accepts_miscellaneous = false; - _category = Command::Category::internal; + _category = Command::Category::internal; } //////////////////////////////////////////////////////////////////////////////// -int CmdZshCompletionIds::execute (std::string& output) -{ +int CmdZshCompletionIds::execute(std::string& output) { // Apply filter. - handleUntil (); - handleRecurrence (); + handleUntil(); + handleRecurrence(); Filter filter; - std::vector filtered; - filter.subset (filtered); + std::vector filtered; + filter.subset(filtered); std::stringstream out; for (auto& task : filtered) - if (task.getStatus () != Task::deleted && - task.getStatus () != Task::completed) - out << task.id - << ':' - << str_replace(task.get ("description"), ":", zshColonReplacement) + if (task.getStatus() != Task::deleted && task.getStatus() != Task::completed) + out << task.id << ':' << str_replace(task.get("description"), ":", zshColonReplacement) << '\n'; - output = out.str (); + output = out.str(); - Context::getContext ().headers.clear (); + Context::getContext().headers.clear(); return 0; } //////////////////////////////////////////////////////////////////////////////// -CmdUUIDs::CmdUUIDs () -{ - _keyword = "uuids"; - _usage = "task uuids"; - _description = "Shows the UUIDs of matching tasks, as a space-separated list"; - _read_only = true; - _displays_id = false; - _needs_gc = true; - _uses_context = false; - _accepts_filter = true; +CmdUUIDs::CmdUUIDs() { + _keyword = "uuids"; + _usage = "task uuids"; + _description = "Shows the UUIDs of matching tasks, as a space-separated list"; + _read_only = true; + _displays_id = false; + _needs_gc = true; + _uses_context = false; + _accepts_filter = true; _accepts_modifications = false; _accepts_miscellaneous = false; - _category = Command::Category::metadata; + _category = Command::Category::metadata; } //////////////////////////////////////////////////////////////////////////////// -int CmdUUIDs::execute (std::string& output) -{ +int CmdUUIDs::execute(std::string& output) { // Apply filter. - handleUntil (); - handleRecurrence (); + handleUntil(); + handleRecurrence(); Filter filter; - std::vector filtered; - filter.subset (filtered); + std::vector filtered; + filter.subset(filtered); - std::vector uuids; + std::vector uuids; uuids.reserve(filtered.size()); - for (auto& task : filtered) - uuids.push_back (task.get ("uuid")); + for (auto& task : filtered) uuids.push_back(task.get("uuid")); - std::sort (uuids.begin (), uuids.end ()); - output = join (" ", uuids) + '\n'; + std::sort(uuids.begin(), uuids.end()); + output = join(" ", uuids) + '\n'; - Context::getContext ().headers.clear (); + Context::getContext().headers.clear(); return 0; } //////////////////////////////////////////////////////////////////////////////// -CmdCompletionUuids::CmdCompletionUuids () -{ - _keyword = "_uuids"; - _usage = "task _uuids"; - _description = "Shows the UUIDs of matching tasks, as a list"; - _read_only = true; - _displays_id = false; - _needs_gc = true; - _uses_context = false; - _accepts_filter = true; +CmdCompletionUuids::CmdCompletionUuids() { + _keyword = "_uuids"; + _usage = "task _uuids"; + _description = "Shows the UUIDs of matching tasks, as a list"; + _read_only = true; + _displays_id = false; + _needs_gc = true; + _uses_context = false; + _accepts_filter = true; _accepts_modifications = false; _accepts_miscellaneous = false; - _category = Command::Category::internal; + _category = Command::Category::internal; } //////////////////////////////////////////////////////////////////////////////// -int CmdCompletionUuids::execute (std::string& output) -{ +int CmdCompletionUuids::execute(std::string& output) { // Apply filter. - handleUntil (); - handleRecurrence (); + handleUntil(); + handleRecurrence(); Filter filter; - std::vector filtered; - filter.subset (filtered); + std::vector filtered; + filter.subset(filtered); - std::vector uuids; + std::vector uuids; uuids.reserve(filtered.size()); - for (auto& task : filtered) - uuids.push_back (task.get ("uuid")); + for (auto& task : filtered) uuids.push_back(task.get("uuid")); - std::sort (uuids.begin (), uuids.end ()); - output = join ("\n", uuids) + '\n'; + std::sort(uuids.begin(), uuids.end()); + output = join("\n", uuids) + '\n'; - Context::getContext ().headers.clear (); + Context::getContext().headers.clear(); return 0; } //////////////////////////////////////////////////////////////////////////////// -CmdZshCompletionUuids::CmdZshCompletionUuids () -{ - _keyword = "_zshuuids"; - _usage = "task _zshuuids"; - _description = "Shows the UUIDs and descriptions of matching tasks"; - _read_only = true; - _displays_id = false; - _needs_gc = true; - _uses_context = false; - _accepts_filter = true; +CmdZshCompletionUuids::CmdZshCompletionUuids() { + _keyword = "_zshuuids"; + _usage = "task _zshuuids"; + _description = "Shows the UUIDs and descriptions of matching tasks"; + _read_only = true; + _displays_id = false; + _needs_gc = true; + _uses_context = false; + _accepts_filter = true; _accepts_modifications = false; _accepts_miscellaneous = false; - _category = Command::Category::internal; + _category = Command::Category::internal; } //////////////////////////////////////////////////////////////////////////////// -int CmdZshCompletionUuids::execute (std::string& output) -{ +int CmdZshCompletionUuids::execute(std::string& output) { // Apply filter. - handleUntil (); - handleRecurrence (); + handleUntil(); + handleRecurrence(); Filter filter; - std::vector filtered; - filter.subset (filtered); + std::vector filtered; + filter.subset(filtered); std::stringstream out; for (auto& task : filtered) - out << task.get ("uuid") - << ':' - << str_replace (task.get ("description"), ":", zshColonReplacement) + out << task.get("uuid") << ':' << str_replace(task.get("description"), ":", zshColonReplacement) << '\n'; - output = out.str (); + output = out.str(); - Context::getContext ().headers.clear (); + Context::getContext().headers.clear(); return 0; } diff --git a/src/commands/CmdIDs.h b/src/commands/CmdIDs.h index 6a345c2df..963b1e29e 100644 --- a/src/commands/CmdIDs.h +++ b/src/commands/CmdIDs.h @@ -27,52 +27,47 @@ #ifndef INCLUDED_CMDIDS #define INCLUDED_CMDIDS -#include #include -class CmdIDs : public Command -{ -public: - CmdIDs (); - int execute (std::string&); +#include -private: - std::string compressIds (const std::vector &); +class CmdIDs : public Command { + public: + CmdIDs(); + int execute(std::string&); + + private: + std::string compressIds(const std::vector&); }; -class CmdCompletionIds : public Command -{ -public: - CmdCompletionIds (); - int execute (std::string&); +class CmdCompletionIds : public Command { + public: + CmdCompletionIds(); + int execute(std::string&); }; -class CmdZshCompletionIds : public Command -{ -public: - CmdZshCompletionIds (); - int execute (std::string&); +class CmdZshCompletionIds : public Command { + public: + CmdZshCompletionIds(); + int execute(std::string&); }; -class CmdUUIDs : public Command -{ -public: - CmdUUIDs (); - int execute (std::string&); +class CmdUUIDs : public Command { + public: + CmdUUIDs(); + int execute(std::string&); }; -class CmdCompletionUuids : public Command -{ -public: - CmdCompletionUuids (); - int execute (std::string&); +class CmdCompletionUuids : public Command { + public: + CmdCompletionUuids(); + int execute(std::string&); }; -class CmdZshCompletionUuids : public Command -{ -public: - CmdZshCompletionUuids (); - int execute (std::string&); +class CmdZshCompletionUuids : public Command { + public: + CmdZshCompletionUuids(); + int execute(std::string&); }; #endif diff --git a/src/commands/CmdImport.cpp b/src/commands/CmdImport.cpp index 19cef20fc..8c7aa3486 100644 --- a/src/commands/CmdImport.cpp +++ b/src/commands/CmdImport.cpp @@ -29,118 +29,102 @@ #include #include -#include #include #include #include #include + +#include #include //////////////////////////////////////////////////////////////////////////////// -CmdImport::CmdImport () -{ - _keyword = "import"; - _usage = "task import [ ...]"; - _description = "Imports JSON files"; - _read_only = false; - _displays_id = false; - _needs_gc = false; - _uses_context = false; - _accepts_filter = false; +CmdImport::CmdImport() { + _keyword = "import"; + _usage = "task import [ ...]"; + _description = "Imports JSON files"; + _read_only = false; + _displays_id = false; + _needs_gc = false; + _uses_context = false; + _accepts_filter = false; _accepts_modifications = false; _accepts_miscellaneous = true; - _category = Command::Category::migration; + _category = Command::Category::migration; } //////////////////////////////////////////////////////////////////////////////// -int CmdImport::execute (std::string&) -{ +int CmdImport::execute(std::string&) { auto rc = 0; auto count = 0; // Get filenames from command line arguments. - auto words = Context::getContext ().cli2.getWords (); - if (! words.size () || - (words.size () == 1 && words[0] == "-")) - { - std::cout << format ("Importing '{1}'\n", "STDIN"); + auto words = Context::getContext().cli2.getWords(); + if (!words.size() || (words.size() == 1 && words[0] == "-")) { + std::cout << format("Importing '{1}'\n", "STDIN"); std::string json; std::string line; - while (std::getline (std::cin, line)) - json += line + '\n'; + while (std::getline(std::cin, line)) json += line + '\n'; - if (nontrivial (json)) - count = import (json); - } - else - { + if (nontrivial(json)) count = import(json); + } else { // Import tasks from all specified files. - for (auto& word : words) - { - File incoming (word); - if (! incoming.exists ()) - throw format ("File '{1}' not found.", word); + for (auto& word : words) { + File incoming(word); + if (!incoming.exists()) throw format("File '{1}' not found.", word); - std::cout << format ("Importing '{1}'\n", word); + std::cout << format("Importing '{1}'\n", word); // Load the file. std::string json; - incoming.read (json); - if (nontrivial (json)) - count += import (json); + incoming.read(json); + if (nontrivial(json)) count += import(json); } } - Context::getContext ().footnote (format ("Imported {1} tasks.", count)); + Context::getContext().footnote(format("Imported {1} tasks.", count)); // Warn the user about multiple occurrences of the same UUID. auto duplicates = false; - for (const auto& [uuid, occurrences] : uuid_occurrences) - { - if (occurrences > 1) - { + for (const auto& [uuid, occurrences] : uuid_occurrences) { + if (occurrences > 1) { duplicates = true; - Context::getContext ().footnote (format ("Input contains UUID '{1}' {2} times.", uuid, occurrences)); + Context::getContext().footnote( + format("Input contains UUID '{1}' {2} times.", uuid, occurrences)); } } if (duplicates) - Context::getContext ().footnote ("Tasks with the same UUID have been merged. Please check the results."); + Context::getContext().footnote( + "Tasks with the same UUID have been merged. Please check the results."); return rc; } //////////////////////////////////////////////////////////////////////////////// -int CmdImport::import (const std::string& input) -{ +int CmdImport::import(const std::string& input) { auto count = 0; - try - { - json::value* root = json::parse (input); - if (root) - { + try { + json::value* root = json::parse(input); + if (root) { // Single object parse. Input looks like: // { ... } - if (root->type () == json::j_object) - { + if (root->type() == json::j_object) { // For each object element... auto root_obj = (json::object*)root; - importSingleTask (root_obj); + importSingleTask(root_obj); ++count; } // Multiple object array. Input looks like: // [ { ... } , { ... } ] - else if (root->type () == json::j_array) - { + else if (root->type() == json::j_array) { auto root_arr = (json::array*)root; // For each object element... - for (auto& element : root_arr->_data) - { + for (auto& element : root_arr->_data) { // For each object element... auto root_obj = (json::object*)element; - importSingleTask (root_obj); + importSingleTask(root_obj); ++count; } } @@ -157,8 +141,7 @@ int CmdImport::import (const std::string& input) // Input looks like: // { ... } // { ... } - catch (std::string& e) - { + catch (std::string& e) { // Make a very cursory check for the old-style format. if (input[0] != '{') { throw e; @@ -166,21 +149,19 @@ int CmdImport::import (const std::string& input) // Read the entire file, so that errors do not result in a partial import. std::vector> objects; - for (auto& line : split (input, '\n')) - { - if (line.length ()) - { - json::value* root = json::parse (line); - if (root && root->type () == json::j_object) - objects.push_back (std::unique_ptr ((json::object *)root)); + for (auto& line : split(input, '\n')) { + if (line.length()) { + json::value* root = json::parse(line); + if (root && root->type() == json::j_object) + objects.push_back(std::unique_ptr((json::object*)root)); else - throw format ("Invalid JSON: {1}", line); + throw format("Invalid JSON: {1}", line); } } // Import the tasks. for (auto& root : objects) { - importSingleTask (root.get()); + importSingleTask(root.get()); ++count; } } @@ -189,24 +170,22 @@ int CmdImport::import (const std::string& input) } //////////////////////////////////////////////////////////////////////////////// -void CmdImport::importSingleTask (json::object* obj) -{ +void CmdImport::importSingleTask(json::object* obj) { // Parse the whole thing, validate the data. - Task task (obj); + Task task(obj); - auto hasGeneratedEntry = not task.has ("entry"); - auto hasExplicitEnd = task.has ("end"); + auto hasGeneratedEntry = not task.has("entry"); + auto hasExplicitEnd = task.has("end"); - task.validate (); + task.validate(); - auto hasGeneratedEnd = not hasExplicitEnd and task.has ("end"); + auto hasGeneratedEnd = not hasExplicitEnd and task.has("end"); // Check whether the imported task is new or a modified existing task. Task before; auto uuid = task.get("uuid"); uuid_occurrences[uuid]++; - if (Context::getContext ().tdb2.get (uuid, before)) - { + if (Context::getContext().tdb2.get(uuid, before)) { // We need to neglect updates from attributes with dynamic defaults // unless they have been explicitly specified on import. // @@ -218,38 +197,28 @@ void CmdImport::importSingleTask (json::object* obj) // The 'modified' attribute is ignored in any case, since if it // were the only difference between the tasks, it would have been // neglected anyway, since it is bumped on each modification. - task.set ("modified", before.get ("modified")); + task.set("modified", before.get("modified")); // Other generated values are replaced by values from existing task, // so that they are ignored on comparison. - if (hasGeneratedEntry) - task.set ("entry", before.get ("entry")); + if (hasGeneratedEntry) task.set("entry", before.get("entry")); - if (hasGeneratedEnd) - task.set ("end", before.get ("end")); + if (hasGeneratedEnd) task.set("end", before.get("end")); - if (before != task) - { + if (before != task) { CmdModify modHelper; - modHelper.checkConsistency (before, task); - modHelper.modifyAndUpdate (before, task); + modHelper.checkConsistency(before, task); + modHelper.modifyAndUpdate(before, task); std::cout << " mod "; - } - else - { + } else { std::cout << " skip "; } - } - else - { - Context::getContext ().tdb2.add (task); + } else { + Context::getContext().tdb2.add(task); std::cout << " add "; } - std::cout << task.get ("uuid") - << ' ' - << task.get ("description") - << '\n'; + std::cout << task.get("uuid") << ' ' << task.get("description") << '\n'; } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/commands/CmdImport.h b/src/commands/CmdImport.h index b27d94362..e46f9a0d5 100644 --- a/src/commands/CmdImport.h +++ b/src/commands/CmdImport.h @@ -27,20 +27,20 @@ #ifndef INCLUDED_CMDIMPORT #define INCLUDED_CMDIMPORT -#include #include #include -class CmdImport : public Command -{ -public: - CmdImport (); - int execute (std::string&); +#include -private: +class CmdImport : public Command { + public: + CmdImport(); + int execute(std::string&); + + private: std::unordered_map uuid_occurrences; - int import (const std::string&); - void importSingleTask (json::object*); + int import(const std::string&); + void importSingleTask(json::object*); }; #endif diff --git a/src/commands/CmdInfo.cpp b/src/commands/CmdInfo.cpp index 3a2771a6d..e6d52d0a6 100644 --- a/src/commands/CmdInfo.cpp +++ b/src/commands/CmdInfo.cpp @@ -28,294 +28,263 @@ // cmake.h include header must come first #include -#include -#include -#include #include -#include #include #include -#include -#include -#include -#include +#include #include +#include +#include +#include +#include +#include +#include + +#include //////////////////////////////////////////////////////////////////////////////// -CmdInfo::CmdInfo () -{ - _keyword = "information"; - _usage = "task information"; - _description = "Shows all data and metadata"; - _read_only = true; +CmdInfo::CmdInfo() { + _keyword = "information"; + _usage = "task information"; + _description = "Shows all data and metadata"; + _read_only = true; // This is inaccurate, but it does prevent a GC. While this doesn't make a // lot of sense, given that the info command shows the ID, it does mimic the // behavior of versions prior to 2.0, which the test suite relies upon. // // Once the test suite is completely modified, this can be corrected. - _displays_id = false; - _needs_gc = false; - _uses_context = false; - _accepts_filter = true; + _displays_id = false; + _needs_gc = false; + _uses_context = false; + _accepts_filter = true; _accepts_modifications = false; _accepts_miscellaneous = false; - _category = Command::Category::metadata; + _category = Command::Category::metadata; } //////////////////////////////////////////////////////////////////////////////// -int CmdInfo::execute (std::string& output) -{ +int CmdInfo::execute(std::string& output) { auto rc = 0; // Apply filter. Filter filter; - std::vector filtered; - filter.subset (filtered); + std::vector filtered; + filter.subset(filtered); - if (! filtered.size ()) - { - Context::getContext ().footnote ("No matches."); + if (!filtered.size()) { + Context::getContext().footnote("No matches."); rc = 1; } // Determine the output date format, which uses a hierarchy of definitions. // rc.dateformat.info // rc.dateformat - auto dateformat = Context::getContext ().config.get ("dateformat.info"); - if (dateformat == "") - dateformat = Context::getContext ().config.get ("dateformat"); + auto dateformat = Context::getContext().config.get("dateformat.info"); + if (dateformat == "") dateformat = Context::getContext().config.get("dateformat"); - auto dateformatanno = Context::getContext ().config.get ("dateformat.annotation"); - if (dateformatanno == "") - dateformatanno = dateformat; + auto dateformatanno = Context::getContext().config.get("dateformat.annotation"); + if (dateformatanno == "") dateformatanno = dateformat; // Render each task. std::stringstream out; - for (auto& task : filtered) - { + for (auto& task : filtered) { Table view; - view.width (Context::getContext ().getWidth ()); - if (Context::getContext ().config.getBoolean ("obfuscate")) - view.obfuscate (); - if (Context::getContext ().color ()) - view.forceColor (); - view.add ("Name"); - view.add ("Value"); - setHeaderUnderline (view); + view.width(Context::getContext().getWidth()); + if (Context::getContext().config.getBoolean("obfuscate")) view.obfuscate(); + if (Context::getContext().color()) view.forceColor(); + view.add("Name"); + view.add("Value"); + setHeaderUnderline(view); Datetime now; // id - auto row = view.addRow (); - view.set (row, 0, "ID"); - view.set (row, 1, (task.id ? format (task.id) : "-")); + auto row = view.addRow(); + view.set(row, 0, "ID"); + view.set(row, 1, (task.id ? format(task.id) : "-")); - std::string status = Lexer::ucFirst (Task::statusToText (task.getStatus ())); + std::string status = Lexer::ucFirst(Task::statusToText(task.getStatus())); // description Color c; - autoColorize (task, c); - auto description = task.get ("description"); - auto indent = Context::getContext ().config.getInteger ("indent.annotation"); + autoColorize(task, c); + auto description = task.get("description"); + auto indent = Context::getContext().config.getInteger("indent.annotation"); - for (auto& anno : task.getAnnotations ()) - description += '\n' - + std::string (indent, ' ') - + Datetime (anno.first.substr (11)).toString (dateformatanno) - + ' ' - + anno.second; + for (auto& anno : task.getAnnotations()) + description += '\n' + std::string(indent, ' ') + + Datetime(anno.first.substr(11)).toString(dateformatanno) + ' ' + anno.second; - row = view.addRow (); - view.set (row, 0, "Description"); - view.set (row, 1, description, c); + row = view.addRow(); + view.set(row, 0, "Description"); + view.set(row, 1, description, c); // status - row = view.addRow (); - view.set (row, 0, "Status"); - view.set (row, 1, status); + row = view.addRow(); + view.set(row, 0, "Status"); + view.set(row, 1, status); // project - if (task.has ("project")) - { - row = view.addRow (); - view.set (row, 0, "Project"); - view.set (row, 1, task.get ("project")); + if (task.has("project")) { + row = view.addRow(); + view.set(row, 0, "Project"); + view.set(row, 1, task.get("project")); } // dependencies: blocked { - auto blocked = task.getDependencyTasks (); - if (blocked.size ()) - { + auto blocked = task.getDependencyTasks(); + if (blocked.size()) { std::stringstream message; - for (auto& block : blocked) - message << block.id << ' ' << block.get ("description") << '\n'; + for (auto& block : blocked) message << block.id << ' ' << block.get("description") << '\n'; - row = view.addRow (); - view.set (row, 0, "This task blocked by"); - view.set (row, 1, message.str ()); + row = view.addRow(); + view.set(row, 0, "This task blocked by"); + view.set(row, 1, message.str()); } } // dependencies: blocking { - auto blocking = task.getBlockedTasks (); - if (blocking.size ()) - { + auto blocking = task.getBlockedTasks(); + if (blocking.size()) { std::stringstream message; - for (auto& block : blocking) - message << block.id << ' ' << block.get ("description") << '\n'; + for (auto& block : blocking) message << block.id << ' ' << block.get("description") << '\n'; - row = view.addRow (); - view.set (row, 0, "This task is blocking"); - view.set (row, 1, message.str ()); + row = view.addRow(); + view.set(row, 0, "This task is blocking"); + view.set(row, 1, message.str()); } } // recur - if (task.has ("recur")) - { - row = view.addRow (); - view.set (row, 0, "Recurrence"); - view.set (row, 1, task.get ("recur")); + if (task.has("recur")) { + row = view.addRow(); + view.set(row, 0, "Recurrence"); + view.set(row, 1, task.get("recur")); } // parent // 2017-01-07: Deprecated in 2.6.0 - if (task.has ("parent")) - { - row = view.addRow (); - view.set (row, 0, "Parent task"); - view.set (row, 1, task.get ("parent")); + if (task.has("parent")) { + row = view.addRow(); + view.set(row, 0, "Parent task"); + view.set(row, 1, task.get("parent")); } // mask // 2017-01-07: Deprecated in 2.6.0 - if (task.has ("mask")) - { - row = view.addRow (); - view.set (row, 0, "Mask"); - view.set (row, 1, task.get ("mask")); + if (task.has("mask")) { + row = view.addRow(); + view.set(row, 0, "Mask"); + view.set(row, 1, task.get("mask")); } // imask // 2017-01-07: Deprecated in 2.6.0 - if (task.has ("imask")) - { - row = view.addRow (); - view.set (row, 0, "Mask Index"); - view.set (row, 1, task.get ("imask")); + if (task.has("imask")) { + row = view.addRow(); + view.set(row, 0, "Mask Index"); + view.set(row, 1, task.get("imask")); } // template - if (task.has ("template")) - { - row = view.addRow (); - view.set (row, 0, "Template task"); - view.set (row, 1, task.get ("template")); + if (task.has("template")) { + row = view.addRow(); + view.set(row, 0, "Template task"); + view.set(row, 1, task.get("template")); } // last - if (task.has ("last")) - { - row = view.addRow (); - view.set (row, 0, "Last instance"); - view.set (row, 1, task.get ("last")); + if (task.has("last")) { + row = view.addRow(); + view.set(row, 0, "Last instance"); + view.set(row, 1, task.get("last")); } // rtype - if (task.has ("rtype")) - { - row = view.addRow (); - view.set (row, 0, "Recurrence type"); - view.set (row, 1, task.get ("rtype")); + if (task.has("rtype")) { + row = view.addRow(); + view.set(row, 0, "Recurrence type"); + view.set(row, 1, task.get("rtype")); } // entry - row = view.addRow (); - view.set (row, 0, "Entered"); - Datetime dt (task.get_date ("entry")); - std::string entry = dt.toString (dateformat); + row = view.addRow(); + view.set(row, 0, "Entered"); + Datetime dt(task.get_date("entry")); + std::string entry = dt.toString(dateformat); std::string age; - auto created = task.get ("entry"); - if (created.length ()) - { - Datetime dt (strtoll (created.c_str (), nullptr, 10)); - age = Duration (now - dt).formatVague (); + auto created = task.get("entry"); + if (created.length()) { + Datetime dt(strtoll(created.c_str(), nullptr, 10)); + age = Duration(now - dt).formatVague(); } - view.set (row, 1, entry + " (" + age + ')'); + view.set(row, 1, entry + " (" + age + ')'); // wait - if (task.has ("wait")) - { - row = view.addRow (); - view.set (row, 0, "Waiting until"); - view.set (row, 1, Datetime (task.get_date ("wait")).toString (dateformat)); + if (task.has("wait")) { + row = view.addRow(); + view.set(row, 0, "Waiting until"); + view.set(row, 1, Datetime(task.get_date("wait")).toString(dateformat)); } // scheduled - if (task.has ("scheduled")) - { - row = view.addRow (); - view.set (row, 0, "Scheduled"); - view.set (row, 1, Datetime (task.get_date ("scheduled")).toString (dateformat)); + if (task.has("scheduled")) { + row = view.addRow(); + view.set(row, 0, "Scheduled"); + view.set(row, 1, Datetime(task.get_date("scheduled")).toString(dateformat)); } // start - if (task.has ("start")) - { - row = view.addRow (); - view.set (row, 0, "Start"); - view.set (row, 1, Datetime (task.get_date ("start")).toString (dateformat)); + if (task.has("start")) { + row = view.addRow(); + view.set(row, 0, "Start"); + view.set(row, 1, Datetime(task.get_date("start")).toString(dateformat)); } // due (colored) - if (task.has ("due")) - { - row = view.addRow (); - view.set (row, 0, "Due"); - view.set (row, 1, Datetime (task.get_date ("due")).toString (dateformat)); + if (task.has("due")) { + row = view.addRow(); + view.set(row, 0, "Due"); + view.set(row, 1, Datetime(task.get_date("due")).toString(dateformat)); } // end - if (task.has ("end")) - { - row = view.addRow (); - view.set (row, 0, "End"); - view.set (row, 1, Datetime (task.get_date ("end")).toString (dateformat)); + if (task.has("end")) { + row = view.addRow(); + view.set(row, 0, "End"); + view.set(row, 1, Datetime(task.get_date("end")).toString(dateformat)); } // until - if (task.has ("until")) - { - row = view.addRow (); - view.set (row, 0, "Until"); - view.set (row, 1, Datetime (task.get_date ("until")).toString (dateformat)); + if (task.has("until")) { + row = view.addRow(); + view.set(row, 0, "Until"); + view.set(row, 1, Datetime(task.get_date("until")).toString(dateformat)); } // modified - if (task.has ("modified")) - { - row = view.addRow (); - view.set (row, 0, "Last modified"); + if (task.has("modified")) { + row = view.addRow(); + view.set(row, 0, "Last modified"); - Datetime mod (task.get_date ("modified")); - std::string age = Duration (now - mod).formatVague (); - view.set (row, 1, mod.toString (dateformat) + " (" + age + ')'); + Datetime mod(task.get_date("modified")); + std::string age = Duration(now - mod).formatVague(); + view.set(row, 1, mod.toString(dateformat) + " (" + age + ')'); } // tags ... - auto tags = task.getTags (); - if (tags.size ()) - { - auto allTags = join (" ", tags); + auto tags = task.getTags(); + if (tags.size()) { + auto allTags = join(" ", tags); - row = view.addRow (); - view.set (row, 0, "Tags"); - view.set (row, 1, allTags); + row = view.addRow(); + view.set(row, 0, "Tags"); + view.set(row, 1, allTags); } // Virtual tags. @@ -323,84 +292,79 @@ int CmdInfo::execute (std::string& output) // Note: This list must match that in Task::hasTag. // Note: This list must match that in ::feedback_reserved_tags. std::string virtualTags = ""; - if (task.hasTag ("ACTIVE")) virtualTags += "ACTIVE "; - if (task.hasTag ("ANNOTATED")) virtualTags += "ANNOTATED "; - if (task.hasTag ("BLOCKED")) virtualTags += "BLOCKED "; - if (task.hasTag ("BLOCKING")) virtualTags += "BLOCKING "; - if (task.hasTag ("CHILD")) virtualTags += "CHILD "; // 2017-01-07: Deprecated in 2.6.0 - if (task.hasTag ("COMPLETED")) virtualTags += "COMPLETED "; - if (task.hasTag ("DELETED")) virtualTags += "DELETED "; - if (task.hasTag ("DUE")) virtualTags += "DUE "; - if (task.hasTag ("DUETODAY")) virtualTags += "DUETODAY "; // 2016-03-29: Deprecated in 2.6.0 - if (task.hasTag ("INSTANCE")) virtualTags += "INSTANCE "; - if (task.hasTag ("LATEST")) virtualTags += "LATEST "; - if (task.hasTag ("MONTH")) virtualTags += "MONTH "; - if (task.hasTag ("ORPHAN")) virtualTags += "ORPHAN "; - if (task.hasTag ("OVERDUE")) virtualTags += "OVERDUE "; - if (task.hasTag ("PARENT")) virtualTags += "PARENT "; // 2017-01-07: Deprecated in 2.6.0 - if (task.hasTag ("PENDING")) virtualTags += "PENDING "; - if (task.hasTag ("PRIORITY")) virtualTags += "PRIORITY "; - if (task.hasTag ("PROJECT")) virtualTags += "PROJECT "; - if (task.hasTag ("QUARTER")) virtualTags += "QUARTER "; - if (task.hasTag ("READY")) virtualTags += "READY "; - if (task.hasTag ("SCHEDULED")) virtualTags += "SCHEDULED "; - if (task.hasTag ("TAGGED")) virtualTags += "TAGGED "; - if (task.hasTag ("TEMPLATE")) virtualTags += "TEMPLATE "; - if (task.hasTag ("TODAY")) virtualTags += "TODAY "; - if (task.hasTag ("TOMORROW")) virtualTags += "TOMORROW "; - if (task.hasTag ("UDA")) virtualTags += "UDA "; - if (task.hasTag ("UNBLOCKED")) virtualTags += "UNBLOCKED "; - if (task.hasTag ("UNTIL")) virtualTags += "UNTIL "; - if (task.hasTag ("WAITING")) virtualTags += "WAITING "; - if (task.hasTag ("WEEK")) virtualTags += "WEEK "; - if (task.hasTag ("YEAR")) virtualTags += "YEAR "; - if (task.hasTag ("YESTERDAY")) virtualTags += "YESTERDAY "; + if (task.hasTag("ACTIVE")) virtualTags += "ACTIVE "; + if (task.hasTag("ANNOTATED")) virtualTags += "ANNOTATED "; + if (task.hasTag("BLOCKED")) virtualTags += "BLOCKED "; + if (task.hasTag("BLOCKING")) virtualTags += "BLOCKING "; + if (task.hasTag("CHILD")) virtualTags += "CHILD "; // 2017-01-07: Deprecated in 2.6.0 + if (task.hasTag("COMPLETED")) virtualTags += "COMPLETED "; + if (task.hasTag("DELETED")) virtualTags += "DELETED "; + if (task.hasTag("DUE")) virtualTags += "DUE "; + if (task.hasTag("DUETODAY")) virtualTags += "DUETODAY "; // 2016-03-29: Deprecated in 2.6.0 + if (task.hasTag("INSTANCE")) virtualTags += "INSTANCE "; + if (task.hasTag("LATEST")) virtualTags += "LATEST "; + if (task.hasTag("MONTH")) virtualTags += "MONTH "; + if (task.hasTag("ORPHAN")) virtualTags += "ORPHAN "; + if (task.hasTag("OVERDUE")) virtualTags += "OVERDUE "; + if (task.hasTag("PARENT")) virtualTags += "PARENT "; // 2017-01-07: Deprecated in 2.6.0 + if (task.hasTag("PENDING")) virtualTags += "PENDING "; + if (task.hasTag("PRIORITY")) virtualTags += "PRIORITY "; + if (task.hasTag("PROJECT")) virtualTags += "PROJECT "; + if (task.hasTag("QUARTER")) virtualTags += "QUARTER "; + if (task.hasTag("READY")) virtualTags += "READY "; + if (task.hasTag("SCHEDULED")) virtualTags += "SCHEDULED "; + if (task.hasTag("TAGGED")) virtualTags += "TAGGED "; + if (task.hasTag("TEMPLATE")) virtualTags += "TEMPLATE "; + if (task.hasTag("TODAY")) virtualTags += "TODAY "; + if (task.hasTag("TOMORROW")) virtualTags += "TOMORROW "; + if (task.hasTag("UDA")) virtualTags += "UDA "; + if (task.hasTag("UNBLOCKED")) virtualTags += "UNBLOCKED "; + if (task.hasTag("UNTIL")) virtualTags += "UNTIL "; + if (task.hasTag("WAITING")) virtualTags += "WAITING "; + if (task.hasTag("WEEK")) virtualTags += "WEEK "; + if (task.hasTag("YEAR")) virtualTags += "YEAR "; + if (task.hasTag("YESTERDAY")) virtualTags += "YESTERDAY "; // If you update the above list, update src/Task.cpp and src/commands/CmdTags.cpp as well. - row = view.addRow (); - view.set (row, 0, "Virtual tags"); - view.set (row, 1, virtualTags); + row = view.addRow(); + view.set(row, 0, "Virtual tags"); + view.set(row, 1, virtualTags); } // uuid - row = view.addRow (); - view.set (row, 0, "UUID"); - auto uuid = task.get ("uuid"); - view.set (row, 1, uuid); + row = view.addRow(); + view.set(row, 0, "UUID"); + auto uuid = task.get("uuid"); + view.set(row, 1, uuid); // Task::urgency - row = view.addRow (); - view.set (row, 0, "Urgency"); - view.set (row, 1, Lexer::trimLeft (format (task.urgency (), 4, 4))); + row = view.addRow(); + view.set(row, 0, "Urgency"); + view.set(row, 1, Lexer::trimLeft(format(task.urgency(), 4, 4))); // Show any UDAs - auto all = task.all (); - for (auto& att: all) - { - if (Context::getContext ().columns.find (att) != Context::getContext ().columns.end ()) - { - Column* col = Context::getContext ().columns[att]; - if (col->is_uda ()) - { - auto value = task.get (att); - if (value != "") - { - row = view.addRow (); - view.set (row, 0, col->label ()); + auto all = task.all(); + for (auto& att : all) { + if (Context::getContext().columns.find(att) != Context::getContext().columns.end()) { + Column* col = Context::getContext().columns[att]; + if (col->is_uda()) { + auto value = task.get(att); + if (value != "") { + row = view.addRow(); + view.set(row, 0, col->label()); - if (col->type () == "date") - value = Datetime (value).toString (dateformat); - else if (col->type () == "duration") - { + if (col->type() == "date") + value = Datetime(value).toString(dateformat); + else if (col->type() == "duration") { Duration iso; std::string::size_type cursor = 0; - if (iso.parse (value, cursor)) - value = (std::string) Variant (iso.toTime_t (), Variant::type_duration); + if (iso.parse(value, cursor)) + value = (std::string)Variant(iso.toTime_t(), Variant::type_duration); else value = "PT0S"; } - view.set (row, 1, value); + view.set(row, 1, value); } } } @@ -408,155 +372,132 @@ int CmdInfo::execute (std::string& output) // Show any orphaned UDAs, which are identified by not being represented in // the context.columns map. - for (auto& att : all) - { - if (att.substr (0, 11) != "annotation_" && - att.substr (0, 5) != "tags_" && - att.substr (0, 4) != "dep_" && - Context::getContext ().columns.find (att) == Context::getContext ().columns.end ()) - { - row = view.addRow (); - view.set (row, 0, '[' + att); - view.set (row, 1, task.get (att) + ']'); + for (auto& att : all) { + if (att.substr(0, 11) != "annotation_" && att.substr(0, 5) != "tags_" && + att.substr(0, 4) != "dep_" && + Context::getContext().columns.find(att) == Context::getContext().columns.end()) { + row = view.addRow(); + view.set(row, 0, '[' + att); + view.set(row, 1, task.get(att) + ']'); } } // Create a second table, containing urgency details, if necessary. Table urgencyDetails; - if (task.urgency () != 0.0) - { - setHeaderUnderline (urgencyDetails); - if (Context::getContext ().color ()) - { - Color alternate (Context::getContext ().config.get ("color.alternate")); - urgencyDetails.colorOdd (alternate); - urgencyDetails.intraColorOdd (alternate); + if (task.urgency() != 0.0) { + setHeaderUnderline(urgencyDetails); + if (Context::getContext().color()) { + Color alternate(Context::getContext().config.get("color.alternate")); + urgencyDetails.colorOdd(alternate); + urgencyDetails.intraColorOdd(alternate); } - if (Context::getContext ().config.getBoolean ("obfuscate")) - urgencyDetails.obfuscate (); - if (Context::getContext ().config.getBoolean ("color")) - view.forceColor (); + if (Context::getContext().config.getBoolean("obfuscate")) urgencyDetails.obfuscate(); + if (Context::getContext().config.getBoolean("color")) view.forceColor(); - urgencyDetails.width (Context::getContext ().getWidth ()); - urgencyDetails.add (""); // Attribute - urgencyDetails.add (""); // Value - urgencyDetails.add (""); // * - urgencyDetails.add (""); // Coefficient - urgencyDetails.add (""); // = - urgencyDetails.add (""); // Result + urgencyDetails.width(Context::getContext().getWidth()); + urgencyDetails.add(""); // Attribute + urgencyDetails.add(""); // Value + urgencyDetails.add(""); // * + urgencyDetails.add(""); // Coefficient + urgencyDetails.add(""); // = + urgencyDetails.add(""); // Result - urgencyTerm (urgencyDetails, "project", task.urgency_project (), Task::urgencyProjectCoefficient); - urgencyTerm (urgencyDetails, "active", task.urgency_active (), Task::urgencyActiveCoefficient); - urgencyTerm (urgencyDetails, "scheduled", task.urgency_scheduled (), Task::urgencyScheduledCoefficient); - urgencyTerm (urgencyDetails, "waiting", task.urgency_waiting (), Task::urgencyWaitingCoefficient); - urgencyTerm (urgencyDetails, "blocked", task.urgency_blocked (), Task::urgencyBlockedCoefficient); - urgencyTerm (urgencyDetails, "blocking", task.urgency_blocking (), Task::urgencyBlockingCoefficient); - urgencyTerm (urgencyDetails, "annotations", task.urgency_annotations (), Task::urgencyAnnotationsCoefficient); - urgencyTerm (urgencyDetails, "tags", task.urgency_tags (), Task::urgencyTagsCoefficient); - urgencyTerm (urgencyDetails, "due", task.urgency_due (), Task::urgencyDueCoefficient); - urgencyTerm (urgencyDetails, "age", task.urgency_age (), Task::urgencyAgeCoefficient); + urgencyTerm(urgencyDetails, "project", task.urgency_project(), + Task::urgencyProjectCoefficient); + urgencyTerm(urgencyDetails, "active", task.urgency_active(), Task::urgencyActiveCoefficient); + urgencyTerm(urgencyDetails, "scheduled", task.urgency_scheduled(), + Task::urgencyScheduledCoefficient); + urgencyTerm(urgencyDetails, "waiting", task.urgency_waiting(), + Task::urgencyWaitingCoefficient); + urgencyTerm(urgencyDetails, "blocked", task.urgency_blocked(), + Task::urgencyBlockedCoefficient); + urgencyTerm(urgencyDetails, "blocking", task.urgency_blocking(), + Task::urgencyBlockingCoefficient); + urgencyTerm(urgencyDetails, "annotations", task.urgency_annotations(), + Task::urgencyAnnotationsCoefficient); + urgencyTerm(urgencyDetails, "tags", task.urgency_tags(), Task::urgencyTagsCoefficient); + urgencyTerm(urgencyDetails, "due", task.urgency_due(), Task::urgencyDueCoefficient); + urgencyTerm(urgencyDetails, "age", task.urgency_age(), Task::urgencyAgeCoefficient); // Tag, Project- and UDA-specific coefficients. - for (auto& var : Task::coefficients) - { - if (var.first.substr (0, 13) == "urgency.user.") - { + for (auto& var : Task::coefficients) { + if (var.first.substr(0, 13) == "urgency.user.") { // urgency.user.project..coefficient auto end = std::string::npos; - if (var.first.substr (13, 8) == "project." && - (end = var.first.find (".coefficient")) != std::string::npos) - { - auto project = var.first.substr (21, end - 21); + if (var.first.substr(13, 8) == "project." && + (end = var.first.find(".coefficient")) != std::string::npos) { + auto project = var.first.substr(21, end - 21); const std::string taskProjectName = task.get("project"); - if (taskProjectName == project || - taskProjectName.find(project + '.') == 0) - { - urgencyTerm (urgencyDetails, "PROJECT " + project, 1.0, var.second); + if (taskProjectName == project || taskProjectName.find(project + '.') == 0) { + urgencyTerm(urgencyDetails, "PROJECT " + project, 1.0, var.second); } } // urgency.user.tag..coefficient - if (var.first.substr (13, 4) == "tag." && - (end = var.first.find (".coefficient")) != std::string::npos) - { - auto name = var.first.substr (17, end - 17); - if (task.hasTag (name)) - urgencyTerm (urgencyDetails, "TAG " + name, 1.0, var.second); + if (var.first.substr(13, 4) == "tag." && + (end = var.first.find(".coefficient")) != std::string::npos) { + auto name = var.first.substr(17, end - 17); + if (task.hasTag(name)) urgencyTerm(urgencyDetails, "TAG " + name, 1.0, var.second); } // urgency.user.keyword..coefficient - if (var.first.substr (13, 8) == "keyword." && - (end = var.first.find (".coefficient")) != std::string::npos) - { - auto keyword = var.first.substr (21, end - 21); - if (task.get ("description").find (keyword) != std::string::npos) - urgencyTerm (urgencyDetails, "KEYWORD " + keyword, 1.0, var.second); + if (var.first.substr(13, 8) == "keyword." && + (end = var.first.find(".coefficient")) != std::string::npos) { + auto keyword = var.first.substr(21, end - 21); + if (task.get("description").find(keyword) != std::string::npos) + urgencyTerm(urgencyDetails, "KEYWORD " + keyword, 1.0, var.second); } } // urgency.uda..coefficient - else if (var.first.substr (0, 12) == "urgency.uda.") - { + else if (var.first.substr(0, 12) == "urgency.uda.") { // urgency.uda..coefficient // urgency.uda...coefficient - auto end = var.first.find (".coefficient"); - if (end != std::string::npos) - { - auto uda = var.first.substr (12, end - 12); - auto dot = uda.find ('.'); - if (dot == std::string::npos) - { + auto end = var.first.find(".coefficient"); + if (end != std::string::npos) { + auto uda = var.first.substr(12, end - 12); + auto dot = uda.find('.'); + if (dot == std::string::npos) { // urgency.uda..coefficient - if (task.has (uda)) - urgencyTerm (urgencyDetails, std::string ("UDA ") + uda, 1.0, var.second); - } - else - { + if (task.has(uda)) + urgencyTerm(urgencyDetails, std::string("UDA ") + uda, 1.0, var.second); + } else { // urgency.uda...coefficient - if (task.get (uda.substr(0, dot)) == uda.substr(dot+1)) - urgencyTerm (urgencyDetails, std::string ("UDA ") + uda, 1.0, var.second); + if (task.get(uda.substr(0, dot)) == uda.substr(dot + 1)) + urgencyTerm(urgencyDetails, std::string("UDA ") + uda, 1.0, var.second); } } } } - row = urgencyDetails.addRow (); - urgencyDetails.set (row, 5, rightJustify ("------", 6)); - row = urgencyDetails.addRow (); - urgencyDetails.set (row, 5, rightJustify (format (task.urgency (), 4, 4), 6)); + row = urgencyDetails.addRow(); + urgencyDetails.set(row, 5, rightJustify("------", 6)); + row = urgencyDetails.addRow(); + urgencyDetails.set(row, 5, rightJustify(format(task.urgency(), 4, 4), 6)); } - out << optionalBlankLine () - << view.render () - << '\n'; + out << optionalBlankLine() << view.render() << '\n'; - if (urgencyDetails.rows () > 0) - out << urgencyDetails.render () - << '\n'; + if (urgencyDetails.rows() > 0) out << urgencyDetails.render() << '\n'; } - output = out.str (); + output = out.str(); return rc; } //////////////////////////////////////////////////////////////////////////////// -void CmdInfo::urgencyTerm ( - Table& view, - const std::string& label, - float measure, - float coefficient) const -{ +void CmdInfo::urgencyTerm(Table& view, const std::string& label, float measure, + float coefficient) const { auto value = measure * coefficient; - if (value != 0.0) - { - auto row = view.addRow (); - view.set (row, 0, " " + label); - view.set (row, 1, rightJustify (format (measure, 5, 3), 6)); - view.set (row, 2, "*"); - view.set (row, 3, rightJustify (format (coefficient, 4, 2), 4)); - view.set (row, 4, "="); - view.set (row, 5, rightJustify (format (value, 5, 3), 6)); + if (value != 0.0) { + auto row = view.addRow(); + view.set(row, 0, " " + label); + view.set(row, 1, rightJustify(format(measure, 5, 3), 6)); + view.set(row, 2, "*"); + view.set(row, 3, rightJustify(format(coefficient, 4, 2), 4)); + view.set(row, 4, "="); + view.set(row, 5, rightJustify(format(value, 5, 3), 6)); } } diff --git a/src/commands/CmdInfo.h b/src/commands/CmdInfo.h index ed3b647bd..06516e920 100644 --- a/src/commands/CmdInfo.h +++ b/src/commands/CmdInfo.h @@ -27,18 +27,18 @@ #ifndef INCLUDED_CMDINFO #define INCLUDED_CMDINFO -#include #include #include -class CmdInfo : public Command -{ -public: - CmdInfo (); - int execute (std::string&); +#include -private: - void urgencyTerm (Table&, const std::string&, float, float) const; +class CmdInfo : public Command { + public: + CmdInfo(); + int execute(std::string&); + + private: + void urgencyTerm(Table&, const std::string&, float, float) const; }; #endif diff --git a/src/commands/CmdLog.cpp b/src/commands/CmdLog.cpp index c58032e57..af3e9f361 100644 --- a/src/commands/CmdLog.cpp +++ b/src/commands/CmdLog.cpp @@ -33,44 +33,40 @@ #include //////////////////////////////////////////////////////////////////////////////// -CmdLog::CmdLog () -{ - _keyword = "log"; - _usage = "task log "; - _description = "Adds a new task that is already completed"; - _read_only = false; - _displays_id = false; - _needs_gc = false; - _uses_context = true; - _accepts_filter = false; +CmdLog::CmdLog() { + _keyword = "log"; + _usage = "task log "; + _description = "Adds a new task that is already completed"; + _read_only = false; + _displays_id = false; + _needs_gc = false; + _uses_context = true; + _accepts_filter = false; _accepts_modifications = true; _accepts_miscellaneous = false; - _category = Command::Category::operation; + _category = Command::Category::operation; } //////////////////////////////////////////////////////////////////////////////// -int CmdLog::execute (std::string& output) -{ +int CmdLog::execute(std::string& output) { // Apply the command line modifications to the new task. Task task; - task.modify (Task::modReplace, true); - task.setStatus (Task::completed); + task.modify(Task::modReplace, true); + task.setStatus(Task::completed); // Cannot log recurring tasks. - if (task.has ("recur")) - throw std::string ("You cannot log recurring tasks."); + if (task.has("recur")) throw std::string("You cannot log recurring tasks."); // Cannot log waiting tasks. - if (task.has ("wait")) - throw std::string ("You cannot log waiting tasks."); + if (task.has("wait")) throw std::string("You cannot log waiting tasks."); - Context::getContext ().tdb2.add (task); + Context::getContext().tdb2.add(task); - if (Context::getContext ().verbose ("project")) - Context::getContext ().footnote (onProjectChange (task)); + if (Context::getContext().verbose("project")) + Context::getContext().footnote(onProjectChange(task)); - if (Context::getContext ().verbose ("new-uuid")) - output = format ("Logged task {1}.\n", task.get ("uuid")); + if (Context::getContext().verbose("new-uuid")) + output = format("Logged task {1}.\n", task.get("uuid")); return 0; } diff --git a/src/commands/CmdLog.h b/src/commands/CmdLog.h index b7b322671..f5561472f 100644 --- a/src/commands/CmdLog.h +++ b/src/commands/CmdLog.h @@ -27,14 +27,14 @@ #ifndef INCLUDED_CMDLOG #define INCLUDED_CMDLOG -#include #include -class CmdLog : public Command -{ -public: - CmdLog (); - int execute (std::string&); +#include + +class CmdLog : public Command { + public: + CmdLog(); + int execute(std::string&); }; #endif diff --git a/src/commands/CmdLogo.cpp b/src/commands/CmdLogo.cpp index c6d3138d8..37efec23d 100644 --- a/src/commands/CmdLogo.cpp +++ b/src/commands/CmdLogo.cpp @@ -32,91 +32,81 @@ #include //////////////////////////////////////////////////////////////////////////////// -CmdLogo::CmdLogo () -{ - _keyword = "logo"; - _usage = "task logo"; - _description = "Displays the Taskwarrior logo"; - _read_only = true; - _displays_id = false; - _needs_gc = false; - _uses_context = false; - _accepts_filter = false; +CmdLogo::CmdLogo() { + _keyword = "logo"; + _usage = "task logo"; + _description = "Displays the Taskwarrior logo"; + _read_only = true; + _displays_id = false; + _needs_gc = false; + _uses_context = false; + _accepts_filter = false; _accepts_modifications = false; _accepts_miscellaneous = false; - _category = Command::Category::misc; + _category = Command::Category::misc; } //////////////////////////////////////////////////////////////////////////////// -int CmdLogo::execute (std::string& output) -{ - static const char* data[] = - { - ".........ABDEF", - ".......BDILNMM", - ".....ACJNLHFEE", - "....AFMMFDEEEE", - "...AFOIDEEEEDD", - "..AFOHDEEEDIOR", - "..DMIDEEEEOXXX", - ".BJMDEEEDMXXXX", - ".ENFEEEEFVXXXX", - "BILDEEEEJXXXXX", - "DLHEEEEDLXXXXX", - "GMFEEEEDKXXXXX", - "GMEEEEEEGTIKOR", - "GMEEEEEEETODDD", - "GMEEEEEEETXRGE", - "GMEEEEEEFVXXSE", - "ENFEEEEEHWXXUE", - "CLHEEEEDLXXXUE", - "AILDEEEDRXXXUE", - ".DNFEEEEPXXXUE", - ".BJMDEEEEPXXUE", - "..DMIDEEEDLXUE", - "..AFOHDEEEDHME", - "...AFOIDEEEEDE", - "....AFMMFDEEEE", - ".....ACJNLHFEE", - ".......BDILNMM", - ".........ABDEF", - "" - }; +int CmdLogo::execute(std::string& output) { + static const char* data[] = {".........ABDEF", + ".......BDILNMM", + ".....ACJNLHFEE", + "....AFMMFDEEEE", + "...AFOIDEEEEDD", + "..AFOHDEEEDIOR", + "..DMIDEEEEOXXX", + ".BJMDEEEDMXXXX", + ".ENFEEEEFVXXXX", + "BILDEEEEJXXXXX", + "DLHEEEEDLXXXXX", + "GMFEEEEDKXXXXX", + "GMEEEEEEGTIKOR", + "GMEEEEEEETODDD", + "GMEEEEEEETXRGE", + "GMEEEEEEFVXXSE", + "ENFEEEEEHWXXUE", + "CLHEEEEDLXXXUE", + "AILDEEEDRXXXUE", + ".DNFEEEEPXXXUE", + ".BJMDEEEEPXXUE", + "..DMIDEEEDLXUE", + "..AFOHDEEEDHME", + "...AFOIDEEEEDE", + "....AFMMFDEEEE", + ".....ACJNLHFEE", + ".......BDILNMM", + ".........ABDEF", + ""}; - if (! Context::getContext ().color ()) - throw std::string ("The logo command requires that color support is enabled."); + if (!Context::getContext().color()) + throw std::string("The logo command requires that color support is enabled."); - std::string indent (Context::getContext ().config.getInteger ("indent.report"), ' '); - output += optionalBlankLine (); + std::string indent(Context::getContext().config.getInteger("indent.report"), ' '); + output += optionalBlankLine(); - for (int line = 0; data[line][0]; ++line) - { + for (int line = 0; data[line][0]; ++line) { output += indent; - for (int c = 0; c < 14; ++c) - { - int value = (int) data[line][c]; + for (int c = 0; c < 14; ++c) { + int value = (int)data[line][c]; if (value == '.') output += " "; - else - { + else { value += 167; - char block [24]; - snprintf (block, 24, "\033[48;5;%dm \033[0m", value); + char block[24]; + snprintf(block, 24, "\033[48;5;%dm \033[0m", value); output += block; } } - for (int c = 13; c >= 0; --c) - { + for (int c = 13; c >= 0; --c) { int value = data[line][c]; if (value == '.') output += " "; - else - { + else { value += 167; - char block [24]; - snprintf (block, 24, "\033[48;5;%dm \033[0m", value); + char block[24]; + snprintf(block, 24, "\033[48;5;%dm \033[0m", value); output += block; } } @@ -124,7 +114,7 @@ int CmdLogo::execute (std::string& output) output += '\n'; } - output += optionalBlankLine (); + output += optionalBlankLine(); return 0; } diff --git a/src/commands/CmdLogo.h b/src/commands/CmdLogo.h index 441ec123a..bea0bfecf 100644 --- a/src/commands/CmdLogo.h +++ b/src/commands/CmdLogo.h @@ -27,14 +27,14 @@ #ifndef INCLUDED_CMDLOGO #define INCLUDED_CMDLOGO -#include #include -class CmdLogo : public Command -{ -public: - CmdLogo (); - int execute (std::string&); +#include + +class CmdLogo : public Command { + public: + CmdLogo(); + int execute(std::string&); }; #endif diff --git a/src/commands/CmdModify.cpp b/src/commands/CmdModify.cpp index 4a16a9427..659c076d3 100644 --- a/src/commands/CmdModify.cpp +++ b/src/commands/CmdModify.cpp @@ -28,197 +28,169 @@ // cmake.h include header must come first #include -#include #include #include -#include #include +#include #include -#define STRING_CMD_MODIFY_TASK_R "Modifying recurring task {1} '{2}'." -#define STRING_CMD_MODIFY_RECUR "This is a recurring task. Do you want to modify all pending recurrences of this same task?" +#include + +#define STRING_CMD_MODIFY_TASK_R "Modifying recurring task {1} '{2}'." +#define STRING_CMD_MODIFY_RECUR \ + "This is a recurring task. Do you want to modify all pending recurrences of this same task?" //////////////////////////////////////////////////////////////////////////////// -CmdModify::CmdModify () -{ - _keyword = "modify"; - _usage = "task modify "; - _description = "Modifies the existing task with provided arguments."; - _read_only = false; - _displays_id = false; - _needs_gc = false; - _uses_context = false; - _accepts_filter = true; +CmdModify::CmdModify() { + _keyword = "modify"; + _usage = "task modify "; + _description = "Modifies the existing task with provided arguments."; + _read_only = false; + _displays_id = false; + _needs_gc = false; + _uses_context = false; + _accepts_filter = true; _accepts_modifications = true; _accepts_miscellaneous = false; - _category = Command::Category::operation; + _category = Command::Category::operation; } //////////////////////////////////////////////////////////////////////////////// -int CmdModify::execute (std::string&) -{ +int CmdModify::execute(std::string &) { auto rc = 0; // Apply filter. Filter filter; - std::vector filtered; - filter.subset (filtered); - if (filtered.size () == 0) - { - Context::getContext ().footnote ("No tasks specified."); + std::vector filtered; + filter.subset(filtered); + if (filtered.size() == 0) { + Context::getContext().footnote("No tasks specified."); return 1; } // Accumulated project change notifications. - std::map projectChanges; + std::map projectChanges; auto count = 0; - if(filtered.size() > 1) { + if (filtered.size() > 1) { feedback_affected("This command will alter {1} tasks.", filtered.size()); } - for (auto& task : filtered) - { - Task before (task); - task.modify (Task::modReplace); + for (auto &task : filtered) { + Task before(task); + task.modify(Task::modReplace); - if (before != task) - { + if (before != task) { // Abort if change introduces inconsistencies. checkConsistency(before, task); - auto question = format ("Modify task {1} '{2}'?", - task.identifier (true), - task.get ("description")); + auto question = + format("Modify task {1} '{2}'?", task.identifier(true), task.get("description")); - if (permission (before.diff (task) + question, filtered.size ())) - { - count += modifyAndUpdate (before, task, &projectChanges); - } - else - { + if (permission(before.diff(task) + question, filtered.size())) { + count += modifyAndUpdate(before, task, &projectChanges); + } else { std::cout << "Task not modified.\n"; rc = 1; - if (_permission_quit) - break; + if (_permission_quit) break; } } } // Now list the project changes. - for (const auto& change : projectChanges) - if (change.first != "") - Context::getContext ().footnote (change.second); + for (const auto &change : projectChanges) + if (change.first != "") Context::getContext().footnote(change.second); - feedback_affected (count == 1 ? "Modified {1} task." : "Modified {1} tasks.", count); + feedback_affected(count == 1 ? "Modified {1} task." : "Modified {1} tasks.", count); return rc; } //////////////////////////////////////////////////////////////////////////////// // TODO Why is this not in Task::validate? -void CmdModify::checkConsistency (Task &before, Task &after) -{ +void CmdModify::checkConsistency(Task &before, Task &after) { // Perform some logical consistency checks. - if (after.has ("recur") && - ! after.has ("due") && - ! before.has ("due")) - throw std::string ("You cannot specify a recurring task without a due date."); + if (after.has("recur") && !after.has("due") && !before.has("due")) + throw std::string("You cannot specify a recurring task without a due date."); - if (before.has ("recur") && - before.has ("due") && - (! after.has ("due") || - after.get ("due") == "")) - throw std::string ("You cannot remove the due date from a recurring task."); + if (before.has("recur") && before.has("due") && (!after.has("due") || after.get("due") == "")) + throw std::string("You cannot remove the due date from a recurring task."); - if (before.has ("recur") && - (! after.has ("recur") || - after.get ("recur") == "")) - throw std::string ("You cannot remove the recurrence from a recurring task."); + if (before.has("recur") && (!after.has("recur") || after.get("recur") == "")) + throw std::string("You cannot remove the recurrence from a recurring task."); } //////////////////////////////////////////////////////////////////////////////// -int CmdModify::modifyAndUpdate ( - Task &before, Task &after, - std::map *projectChanges /* = NULL */) -{ +int CmdModify::modifyAndUpdate(Task &before, Task &after, + std::map *projectChanges /* = NULL */) { // This task. auto count = 1; - updateRecurrenceMask (after); - feedback_affected ("Modifying task {1} '{2}'.", after); - feedback_unblocked (after); - Context::getContext ().tdb2.modify (after); - if (Context::getContext ().verbose ("project") && projectChanges) - (*projectChanges)[after.get ("project")] = onProjectChange (before, after); + updateRecurrenceMask(after); + feedback_affected("Modifying task {1} '{2}'.", after); + feedback_unblocked(after); + Context::getContext().tdb2.modify(after); + if (Context::getContext().verbose("project") && projectChanges) + (*projectChanges)[after.get("project")] = onProjectChange(before, after); // Task has siblings - modify them. - if (after.has ("parent")) - count += modifyRecurrenceSiblings (after, projectChanges); + if (after.has("parent")) count += modifyRecurrenceSiblings(after, projectChanges); // Task has child tasks - modify them. - else if (after.get ("status") == "recurring") - count += modifyRecurrenceParent (after, projectChanges); + else if (after.get("status") == "recurring") + count += modifyRecurrenceParent(after, projectChanges); return count; } //////////////////////////////////////////////////////////////////////////////// -int CmdModify::modifyRecurrenceSiblings ( - Task &task, - std::map *projectChanges /* = NULL */) -{ +int CmdModify::modifyRecurrenceSiblings( + Task &task, std::map *projectChanges /* = NULL */) { auto count = 0; - if ((Context::getContext ().config.get ("recurrence.confirmation") == "prompt" - && confirm (STRING_CMD_MODIFY_RECUR)) || - Context::getContext ().config.getBoolean ("recurrence.confirmation")) - { - std::vector siblings = Context::getContext ().tdb2.siblings (task); - for (auto& sibling : siblings) - { - Task alternate (sibling); - sibling.modify (Task::modReplace); - updateRecurrenceMask (sibling); + if ((Context::getContext().config.get("recurrence.confirmation") == "prompt" && + confirm(STRING_CMD_MODIFY_RECUR)) || + Context::getContext().config.getBoolean("recurrence.confirmation")) { + std::vector siblings = Context::getContext().tdb2.siblings(task); + for (auto &sibling : siblings) { + Task alternate(sibling); + sibling.modify(Task::modReplace); + updateRecurrenceMask(sibling); ++count; - feedback_affected (STRING_CMD_MODIFY_TASK_R, sibling); - feedback_unblocked (sibling); - Context::getContext ().tdb2.modify (sibling); - if (Context::getContext ().verbose ("project") && projectChanges) - (*projectChanges)[sibling.get ("project")] = onProjectChange (alternate, sibling); + feedback_affected(STRING_CMD_MODIFY_TASK_R, sibling); + feedback_unblocked(sibling); + Context::getContext().tdb2.modify(sibling); + if (Context::getContext().verbose("project") && projectChanges) + (*projectChanges)[sibling.get("project")] = onProjectChange(alternate, sibling); } // Modify the parent Task parent; - Context::getContext ().tdb2.get (task.get ("parent"), parent); - parent.modify (Task::modReplace); - Context::getContext ().tdb2.modify (parent); + Context::getContext().tdb2.get(task.get("parent"), parent); + parent.modify(Task::modReplace); + Context::getContext().tdb2.modify(parent); } return count; } //////////////////////////////////////////////////////////////////////////////// -int CmdModify::modifyRecurrenceParent ( - Task &task, - std::map *projectChanges /* = NULL */) -{ +int CmdModify::modifyRecurrenceParent( + Task &task, std::map *projectChanges /* = NULL */) { auto count = 0; - auto children = Context::getContext ().tdb2.children (task); - if (children.size () && - ((Context::getContext ().config.get ("recurrence.confirmation") == "prompt" - && confirm (STRING_CMD_MODIFY_RECUR)) || - Context::getContext ().config.getBoolean ("recurrence.confirmation"))) - { - for (auto& child : children) - { - Task alternate (child); - child.modify (Task::modReplace); - updateRecurrenceMask (child); - Context::getContext ().tdb2.modify (child); - if (Context::getContext ().verbose ("project") && projectChanges) - (*projectChanges)[child.get ("project")] = onProjectChange (alternate, child); + auto children = Context::getContext().tdb2.children(task); + if (children.size() && + ((Context::getContext().config.get("recurrence.confirmation") == "prompt" && + confirm(STRING_CMD_MODIFY_RECUR)) || + Context::getContext().config.getBoolean("recurrence.confirmation"))) { + for (auto &child : children) { + Task alternate(child); + child.modify(Task::modReplace); + updateRecurrenceMask(child); + Context::getContext().tdb2.modify(child); + if (Context::getContext().verbose("project") && projectChanges) + (*projectChanges)[child.get("project")] = onProjectChange(alternate, child); ++count; - feedback_affected (STRING_CMD_MODIFY_TASK_R, child); + feedback_affected(STRING_CMD_MODIFY_TASK_R, child); } } @@ -226,4 +198,3 @@ int CmdModify::modifyRecurrenceParent ( } //////////////////////////////////////////////////////////////////////////////// - diff --git a/src/commands/CmdModify.h b/src/commands/CmdModify.h index 1dcfb4fd5..17313e798 100644 --- a/src/commands/CmdModify.h +++ b/src/commands/CmdModify.h @@ -27,21 +27,21 @@ #ifndef INCLUDED_CMDMODIFY #define INCLUDED_CMDMODIFY -#include #include -class CmdModify : public Command -{ -public: - CmdModify (); - int execute (std::string&); - void checkConsistency (Task &before, Task &after); - int modifyAndUpdate (Task &before, Task &after, - std::map *projectChanges = nullptr); - int modifyRecurrenceSiblings (Task &task, - std::map *projectChanges = nullptr); - int modifyRecurrenceParent (Task &task, - std::map *projectChanges = nullptr); +#include + +class CmdModify : public Command { + public: + CmdModify(); + int execute(std::string &); + void checkConsistency(Task &before, Task &after); + int modifyAndUpdate(Task &before, Task &after, + std::map *projectChanges = nullptr); + int modifyRecurrenceSiblings(Task &task, + std::map *projectChanges = nullptr); + int modifyRecurrenceParent(Task &task, + std::map *projectChanges = nullptr); }; #endif diff --git a/src/commands/CmdNews.cpp b/src/commands/CmdNews.cpp index 419372095..cb1e8a3c0 100644 --- a/src/commands/CmdNews.cpp +++ b/src/commands/CmdNews.cpp @@ -28,17 +28,18 @@ // cmake.h include header must come first #include -#include -#include -#include -#include #include #include #include -#include +#include #include -#include #include +#include +#include + +#include +#include +#include /* Adding a new version: * @@ -49,67 +50,56 @@ */ //////////////////////////////////////////////////////////////////////////////// -CmdNews::CmdNews () -{ - _keyword = "news"; - _usage = "task news"; - _description = "Displays news about the recent releases"; - _read_only = true; - _displays_id = false; - _needs_gc = false; - _uses_context = false; - _accepts_filter = false; +CmdNews::CmdNews() { + _keyword = "news"; + _usage = "task news"; + _description = "Displays news about the recent releases"; + _read_only = true; + _displays_id = false; + _needs_gc = false; + _uses_context = false; + _accepts_filter = false; _accepts_modifications = false; _accepts_miscellaneous = false; - _category = Command::Category::misc; + _category = Command::Category::misc; } //////////////////////////////////////////////////////////////////////////////// -static void signal_handler (int s) -{ - if (s == SIGINT) - { +static void signal_handler(int s) { + if (s == SIGINT) { Color footnote; - if (Context::getContext ().color ()) { - if (Context::getContext ().config.has ("color.footnote")) - footnote = Color (Context::getContext ().config.get ("color.footnote")); + if (Context::getContext().color()) { + if (Context::getContext().config.has("color.footnote")) + footnote = Color(Context::getContext().config.get("color.footnote")); } std::cout << "\n\nCome back and read about new features later!\n"; - std::cout << footnote.colorize ( - "\nIf you enjoy Taskwarrior, please consider supporting the project at:\n" - " https://github.com/sponsors/GothenburgBitFactory/\n" - ); - exit (1); + std::cout << footnote.colorize( + "\nIf you enjoy Taskwarrior, please consider supporting the project at:\n" + " https://github.com/sponsors/GothenburgBitFactory/\n"); + exit(1); } } -void wait_for_enter () -{ - signal (SIGINT, signal_handler); +void wait_for_enter() { + signal(SIGINT, signal_handler); std::string dummy; std::cout << "\nPress enter to continue.."; - std::getline (std::cin, dummy); + std::getline(std::cin, dummy); std::cout << "\33[2K\033[A\33[2K"; // Erase current line, move up, and erase again - signal (SIGINT, SIG_DFL); + signal(SIGINT, SIG_DFL); } //////////////////////////////////////////////////////////////////////////////// // Holds information about single improvement / bug. // -NewsItem::NewsItem ( - Version version, - const std::string& title, - const std::string& bg_title, - const std::string& background, - const std::string& punchline, - const std::string& update, - const std::string& reasoning, - const std::string& actions -) { +NewsItem::NewsItem(Version version, const std::string& title, const std::string& bg_title, + const std::string& background, const std::string& punchline, + const std::string& update, const std::string& reasoning, + const std::string& actions) { _version = version; _title = title; _bg_title = bg_title; @@ -120,57 +110,50 @@ NewsItem::NewsItem ( _actions = actions; } -void NewsItem::render () { - auto config = Context::getContext ().config; +void NewsItem::render() { + auto config = Context::getContext().config; Color header; Color footnote; Color bold; Color underline; - if (Context::getContext ().color ()) { - bold = Color ("bold"); - underline = Color ("underline"); - if (config.has ("color.header")) - header = Color (config.get ("color.header")); - if (config.has ("color.footnote")) - footnote = Color (config.get ("color.footnote")); + if (Context::getContext().color()) { + bold = Color("bold"); + underline = Color("underline"); + if (config.has("color.header")) header = Color(config.get("color.header")); + if (config.has("color.footnote")) footnote = Color(config.get("color.footnote")); } // TODO: For some reason, bold cannot be blended in 256-color terminals // Apply this workaround of colorizing twice. - std::cout << bold.colorize (header.colorize (format ("{1} ({2})\n", _title, _version))); - if (_background.size ()) { - if (_bg_title.empty ()) - _bg_title = "Background"; + std::cout << bold.colorize(header.colorize(format("{1} ({2})\n", _title, _version))); + if (_background.size()) { + if (_bg_title.empty()) _bg_title = "Background"; - std::cout << "\n " << underline.colorize (_bg_title) << std::endl - << _background << std::endl; + std::cout << "\n " << underline.colorize(_bg_title) << std::endl << _background << std::endl; } - wait_for_enter (); + wait_for_enter(); - std::cout << " " << underline.colorize (format ("What changed in {1}?\n", _version)); - if (_punchline.size ()) - std::cout << footnote.colorize (format ("{1}\n", _punchline)); + std::cout << " " << underline.colorize(format("What changed in {1}?\n", _version)); + if (_punchline.size()) std::cout << footnote.colorize(format("{1}\n", _punchline)); - if (_update.size ()) - std::cout << format ("{1}\n", _update); + if (_update.size()) std::cout << format("{1}\n", _update); - wait_for_enter (); + wait_for_enter(); - if (_reasoning.size ()) { - std::cout << " " << underline.colorize ("What was the motivation behind this feature?\n") + if (_reasoning.size()) { + std::cout << " " << underline.colorize("What was the motivation behind this feature?\n") << _reasoning << std::endl; - wait_for_enter (); + wait_for_enter(); } - if (_actions.size ()) { - std::cout << " " << underline.colorize ("What do I have to do?\n") - << _actions << std::endl; - wait_for_enter (); + if (_actions.size()) { + std::cout << " " << underline.colorize("What do I have to do?\n") << _actions << std::endl; + wait_for_enter(); } } -std::vector NewsItem::all () { +std::vector NewsItem::all() { std::vector items; version2_6_0(items); version3_0_0(items); @@ -192,484 +175,420 @@ std::vector NewsItem::all () { // - The .by attribute modifier // - Exporting a report // - Multi-day holidays -void NewsItem::version2_6_0 (std::vector& items) { +void NewsItem::version2_6_0(std::vector& items) { Version version("2.6.0"); ///////////////////////////////////////////////////////////////////////////// // - Writeable context // Detect whether user uses any contexts - auto config = Context::getContext ().config; + auto config = Context::getContext().config; std::stringstream advice; - auto defined = CmdContext::getContexts (); - if (defined.size ()) - { + auto defined = CmdContext::getContexts(); + if (defined.size()) { // Detect the old-style contexts std::vector old_style; - std::copy_if ( - defined.begin(), - defined.end(), - std::back_inserter(old_style), - [&](auto& name){return config.has ("context." + name);} - ); + std::copy_if(defined.begin(), defined.end(), std::back_inserter(old_style), + [&](auto& name) { return config.has("context." + name); }); - if (old_style.size ()) - { - advice << format ( - " You have {1} defined contexts, out of which {2} are old-style:\n", - defined.size (), - std::count_if ( - defined.begin (), - defined.end (), - [&](auto& name){return config.has ("context." + name);} - )); + if (old_style.size()) { + advice << format(" You have {1} defined contexts, out of which {2} are old-style:\n", + defined.size(), + std::count_if(defined.begin(), defined.end(), + [&](auto& name) { return config.has("context." + name); })); - for (auto context: defined) { - std::string old_definition = config.get ("context." + context); - if (old_definition != "") - advice << format (" * {1}: {2}\n", context, old_definition); + for (auto context : defined) { + std::string old_definition = config.get("context." + context); + if (old_definition != "") advice << format(" * {1}: {2}\n", context, old_definition); } advice << "\n" " These need to be migrated to new-style, which uses context..read and\n" " context..write config variables. Please run the following commands:\n"; - for (auto context: defined) { - std::string old_definition = config.get ("context." + context); + for (auto context : defined) { + std::string old_definition = config.get("context." + context); if (old_definition != "") - advice << format (" $ task context define {1} '{2}'\n", context, old_definition); + advice << format(" $ task context define {1} '{2}'\n", context, old_definition); } - advice << "\n" - " Please check these filters are also valid modifications. If a context filter is not\n" - " a valid modification, you can set the context..write configuration variable to\n" - " specify the write context explicitly. Read more in CONTEXT section of man taskrc."; - } - else + advice + << "\n" + " Please check these filters are also valid modifications. If a context filter is " + "not\n" + " a valid modification, you can set the context..write configuration variable " + "to\n" + " specify the write context explicitly. Read more in CONTEXT section of man taskrc."; + } else advice << " You don't have any old-style contexts defined, so you're good to go as is!"; - } - else + } else advice << " You don't have any contexts defined, so you're good to go as is!\n" " Read more about how to use contexts in CONTEXT section of 'man task'."; - NewsItem writeable_context ( - version, - "'Writeable' context", - "Background - what is context?", - " The 'context' is a feature (introduced in 2.5.0) that allows users to apply a\n" - " predefined filter to all task reports.\n" - " \n" - " $ task context define work \"project:Work or +urgent\"\n" - " $ task context work\n" - " Context 'work' set. Use 'task context none' to remove.\n" - " \n" - " Now if we proceed to add two tasks:\n" - " $ task add Talk to Jeff pro:Work\n" - " $ task add Call mom pro:Personal\n" - " \n" - " $ task\n" - " ID Age Project Description Urg\n" - " 1 16s Work Talk to Jeff 1\n" - " \n" - " The task \"Call mom\" will not be listed, because it does not match\n" - " the active context (its project is 'Personal' and not 'Work').", - " The currently active context definition is now applied as default modifications\n" - " when creating new tasks using 'task add' and 'task log'.", - " \n" - " Consider following example, using context 'work' defined as 'project:Work' above:\n" - " \n" - " $ task context work\n" - " $ task add Talk to Jeff\n" - " $ task\n" - " ID Age Project Description Urg \n" - " 1 1s Work Talk to Jeff 1\n" - " ^^^^^^^\n" - " \n" - " Note that project attribute was set to 'Work' automatically.", - " This was a popular feature request. Now, if you have a context active,\n" - " newly added tasks no longer \"fall outside\" of the context by default.", - advice.str () - ); + NewsItem writeable_context( + version, "'Writeable' context", "Background - what is context?", + " The 'context' is a feature (introduced in 2.5.0) that allows users to apply a\n" + " predefined filter to all task reports.\n" + " \n" + " $ task context define work \"project:Work or +urgent\"\n" + " $ task context work\n" + " Context 'work' set. Use 'task context none' to remove.\n" + " \n" + " Now if we proceed to add two tasks:\n" + " $ task add Talk to Jeff pro:Work\n" + " $ task add Call mom pro:Personal\n" + " \n" + " $ task\n" + " ID Age Project Description Urg\n" + " 1 16s Work Talk to Jeff 1\n" + " \n" + " The task \"Call mom\" will not be listed, because it does not match\n" + " the active context (its project is 'Personal' and not 'Work').", + " The currently active context definition is now applied as default modifications\n" + " when creating new tasks using 'task add' and 'task log'.", + " \n" + " Consider following example, using context 'work' defined as 'project:Work' above:\n" + " \n" + " $ task context work\n" + " $ task add Talk to Jeff\n" + " $ task\n" + " ID Age Project Description Urg \n" + " 1 1s Work Talk to Jeff 1\n" + " ^^^^^^^\n" + " \n" + " Note that project attribute was set to 'Work' automatically.", + " This was a popular feature request. Now, if you have a context active,\n" + " newly added tasks no longer \"fall outside\" of the context by default.", + advice.str()); items.push_back(writeable_context); ///////////////////////////////////////////////////////////////////////////// // - 64-bit datetime support - NewsItem uint64_support ( - version, - "Support for 64-bit timestamps and numeric values", - "", - "", - " Taskwarrior now supports 64-bit timestamps, making it possible to set due dates\n" - " and other date attributes beyond 19 January 2038 (limit of 32-bit timestamps).\n", - " The current limit is 31 December 9999 for display reasons (last 4-digit year).", - " With each year passing by faster than the last, setting tasks for 2040s\n" - " is not as unfeasible as it once was.", - " Don't forget that 50-year anniversary and 'task add' a long-term task today!" - ); + NewsItem uint64_support( + version, "Support for 64-bit timestamps and numeric values", "", "", + " Taskwarrior now supports 64-bit timestamps, making it possible to set due dates\n" + " and other date attributes beyond 19 January 2038 (limit of 32-bit timestamps).\n", + " The current limit is 31 December 9999 for display reasons (last 4-digit year).", + " With each year passing by faster than the last, setting tasks for 2040s\n" + " is not as unfeasible as it once was.", + " Don't forget that 50-year anniversary and 'task add' a long-term task today!"); items.push_back(uint64_support); ///////////////////////////////////////////////////////////////////////////// // - Waiting is a virtual status - NewsItem waiting_status ( - version, - "Deprecation of the status:waiting", - "", - " If a task has a 'wait' attribute set to a date in the future, it is modified\n" - " to have a 'waiting' status. Once that date is no longer in the future, the status\n" - " is modified to back to 'pending'.", - " The 'waiting' value of status is deprecated, instead users should use +WAITING\n" - " virtual tag, or explicitly query for wait.after:now (the two are equivalent).", - " \n" - " The status:waiting query still works in 2.6.0, but support will be dropped in 3.0.", - "", - " In your custom report definitions, the following expressions should be replaced:\n" - " * 'status:pending or status:waiting' should be replaced by 'status:pending'\n" - " * 'status:pending' should be replaced by 'status:pending -WAITING'" - ); + NewsItem waiting_status( + version, "Deprecation of the status:waiting", "", + " If a task has a 'wait' attribute set to a date in the future, it is modified\n" + " to have a 'waiting' status. Once that date is no longer in the future, the status\n" + " is modified to back to 'pending'.", + " The 'waiting' value of status is deprecated, instead users should use +WAITING\n" + " virtual tag, or explicitly query for wait.after:now (the two are equivalent).", + " \n" + " The status:waiting query still works in 2.6.0, but support will be dropped in 3.0.", + "", + " In your custom report definitions, the following expressions should be replaced:\n" + " * 'status:pending or status:waiting' should be replaced by 'status:pending'\n" + " * 'status:pending' should be replaced by 'status:pending -WAITING'"); items.push_back(waiting_status); ///////////////////////////////////////////////////////////////////////////// // - Support for environment variables in the taskrc - NewsItem env_vars ( - version, - "Environment variables in the taskrc", - "", - "", - " Taskwarrior now supports expanding environment variables in the taskrc file,\n" - " allowing users to customize the behaviour of 'task' based on the current env.\n", - " The environment variables can either be used in paths, or as separate values:\n" - " data.location=$XDG_DATA_HOME/task/\n" - " default.project=$PROJECT", - "", - "" - ); + NewsItem env_vars( + version, "Environment variables in the taskrc", "", "", + " Taskwarrior now supports expanding environment variables in the taskrc file,\n" + " allowing users to customize the behaviour of 'task' based on the current env.\n", + " The environment variables can either be used in paths, or as separate values:\n" + " data.location=$XDG_DATA_HOME/task/\n" + " default.project=$PROJECT", + "", ""); items.push_back(env_vars); ///////////////////////////////////////////////////////////////////////////// // - Reports outside of context - NewsItem contextless_reports ( - version, - "Context-less reports", - "", - " By default, every report is affected by currently active context.", - " You can now make a selected report ignore currently active context by setting\n" - " 'report..context' configuration variable to 0.", - "", - " This is useful for users who utilize a single place (such as project:Inbox)\n" - " to collect their new tasks that are then triaged on a regular basis\n" - " (such as in GTD methodology).\n" - " \n" - " In such a case, defining a report that filters for project:Inbox and making it\n" - " fully accessible from any context is a major usability improvement.", - "" - ); + NewsItem contextless_reports( + version, "Context-less reports", "", + " By default, every report is affected by currently active context.", + " You can now make a selected report ignore currently active context by setting\n" + " 'report..context' configuration variable to 0.", + "", + " This is useful for users who utilize a single place (such as project:Inbox)\n" + " to collect their new tasks that are then triaged on a regular basis\n" + " (such as in GTD methodology).\n" + " \n" + " In such a case, defining a report that filters for project:Inbox and making it\n" + " fully accessible from any context is a major usability improvement.", + ""); items.push_back(contextless_reports); ///////////////////////////////////////////////////////////////////////////// // - Exporting a particular report - NewsItem exportable_reports ( - version, - "Exporting a particular report", - "", - "", - " You can now export the tasks listed by a particular report as JSON by simply\n" - " calling 'task export '.\n", - " The export mirrors the filter and the sort order of the report.", - " This feature can be used to quickly process the data displayed in a particular\n" - " report using other CLI tools. For example, the following oneliner\n" - " \n" - " $ task export next | jq '.[].urgency' | datamash mean 1\n" - " 3.3455535142857\n" - " \n" - " combines jq and GNU datamash to compute average urgency of the tasks displayed\n" - " in the 'next' report.", - "" - ); + NewsItem exportable_reports( + version, "Exporting a particular report", "", "", + " You can now export the tasks listed by a particular report as JSON by simply\n" + " calling 'task export '.\n", + " The export mirrors the filter and the sort order of the report.", + " This feature can be used to quickly process the data displayed in a particular\n" + " report using other CLI tools. For example, the following oneliner\n" + " \n" + " $ task export next | jq '.[].urgency' | datamash mean 1\n" + " 3.3455535142857\n" + " \n" + " combines jq and GNU datamash to compute average urgency of the tasks displayed\n" + " in the 'next' report.", + ""); items.push_back(exportable_reports); ///////////////////////////////////////////////////////////////////////////// // - Multi-day holidays - NewsItem multi_holidays ( - version, - "Multi-day holidays", - "", - " Holidays are currently used in 'task calendar' to visualize the workload during\n" - " the upcoming weeks/months. Up to date country-specific holiday data files can be\n" - " obtained from our website, holidata.net.", - " Instead of single-day holiday entries only, Taskwarrior now supports holidays\n" - " that span a range of days (i.e. vacation).\n", - " Use a holiday..start and holiday..end to configure a multi-day holiday:\n" - " \n" - " holiday.sysadmin.name=System Administrator Appreciation Week\n" - " holiday.sysadmin.start=20100730\n" - " holiday.sysadmin.end=20100805", - "", - "" - ); + NewsItem multi_holidays( + version, "Multi-day holidays", "", + " Holidays are currently used in 'task calendar' to visualize the workload during\n" + " the upcoming weeks/months. Up to date country-specific holiday data files can be\n" + " obtained from our website, holidata.net.", + " Instead of single-day holiday entries only, Taskwarrior now supports holidays\n" + " that span a range of days (i.e. vacation).\n", + " Use a holiday..start and holiday..end to configure a multi-day holiday:\n" + " \n" + " holiday.sysadmin.name=System Administrator Appreciation Week\n" + " holiday.sysadmin.start=20100730\n" + " holiday.sysadmin.end=20100805", + "", ""); items.push_back(multi_holidays); ///////////////////////////////////////////////////////////////////////////// // - Unicode 12 - NewsItem unicode_12 ( - version, - "Extended Unicode support (Unicode 12)", - "", - "", - " The support for Unicode character set was improved to support Unicode 12.\n" - " This means better support for various language-specific characters - and emojis!", - "", - " Extended unicode support for language-specific characters helps non-English speakers.\n" - " While most users don't enter emojis as task metadata, automated task creation tools,\n" - " such as bugwarrior, might create tasks with exotic Unicode data.", - " You can try it out - 'task add Prepare for an 👽 invasion!'" - ); + NewsItem unicode_12( + version, "Extended Unicode support (Unicode 12)", "", "", + " The support for Unicode character set was improved to support Unicode 12.\n" + " This means better support for various language-specific characters - and emojis!", + "", + " Extended unicode support for language-specific characters helps non-English speakers.\n" + " While most users don't enter emojis as task metadata, automated task creation tools,\n" + " such as bugwarrior, might create tasks with exotic Unicode data.", + " You can try it out - 'task add Prepare for an 👽 invasion!'"); items.push_back(unicode_12); ///////////////////////////////////////////////////////////////////////////// // - The .by attribute modifier - NewsItem by_modifier ( - version, - "The .by attribute modifier", - "", - "", - " A new attribute modifier '.by' was introduced, equivalent to the operator '<='.\n", - " This modifier can be used to list all tasks due by the end of the months,\n" - " including the last day of the month, using: 'due.by:eom' query", - " There was no convenient way to express '<=' relation using attribute modifiers.\n" - " As a workaround, instead of 'due.by:eom' one could use 'due.before:eom+1d',\n" - " but that requires a certain amount of mental overhead.", - "" - ); + NewsItem by_modifier( + version, "The .by attribute modifier", "", "", + " A new attribute modifier '.by' was introduced, equivalent to the operator '<='.\n", + " This modifier can be used to list all tasks due by the end of the months,\n" + " including the last day of the month, using: 'due.by:eom' query", + " There was no convenient way to express '<=' relation using attribute modifiers.\n" + " As a workaround, instead of 'due.by:eom' one could use 'due.before:eom+1d',\n" + " but that requires a certain amount of mental overhead.", + ""); items.push_back(by_modifier); ///////////////////////////////////////////////////////////////////////////// // - Context-specific configuration overrides - NewsItem context_config ( - version, - "Context-specific configuration overrides", - "", - "", - " Any context can now define context-specific configuration overrides\n" - " via context..rc.=.\n", - " This allows the user to customize the behaviour of Taskwarrior in a given context,\n" - " for example, to change the default command in the 'work' context to 'overdue':\n" - "\n" - " $ task config context.work.rc.default.command overdue\n" - "\n" - " Another example would be to ensure that while context 'work' is active, tasks get\n" - " stored in a ~/.worktasks directory:\n" - "\n" - " $ task config context.work.rc.data.location=~/.worktasks", - "", - "" - ); + NewsItem context_config( + version, "Context-specific configuration overrides", "", "", + " Any context can now define context-specific configuration overrides\n" + " via context..rc.=.\n", + " This allows the user to customize the behaviour of Taskwarrior in a given context,\n" + " for example, to change the default command in the 'work' context to 'overdue':\n" + "\n" + " $ task config context.work.rc.default.command overdue\n" + "\n" + " Another example would be to ensure that while context 'work' is active, tasks get\n" + " stored in a ~/.worktasks directory:\n" + "\n" + " $ task config context.work.rc.data.location=~/.worktasks", + "", ""); items.push_back(context_config); ///////////////////////////////////////////////////////////////////////////// // - XDG config home support - NewsItem xdg_support ( - version, - "Support for XDG Base Directory Specification", - "", - " The XDG Base Directory specification provides standard locations to store\n" - " application data, configuration, state, and cached data in order to keep $HOME\n" - " clutter-free. The locations are usually set to ~/.local/share, ~/.config,\n" - " ~/.local/state and ~/.cache respectively.", - " If taskrc is not found at '~/.taskrc', Taskwarrior will attempt to find it\n" - " at '$XDG_CONFIG_HOME/task/taskrc' (defaults to '~/.config/task/taskrc').", - "", - " This allows users to fully follow XDG Base Directory Spec by moving their taskrc:\n" - " $ mkdir $XDG_CONFIG_HOME/task\n" - " $ mv ~/.taskrc $XDG_CONFIG_HOME/task/taskrc\n\n" - " and further setting:\n" - " data.location=$XDG_DATA_HOME/task/\n" - " hooks.location=$XDG_CONFIG_HOME/task/hooks/\n\n" - " Solutions in the past required symlinks or more cumbersome configuration overrides.", - " If you configure your data.location and hooks.location as above, ensure\n" - " that the XDG_DATA_HOME and XDG_CONFIG_HOME environment variables are set,\n" - " otherwise they're going to expand to empty string. Alternatively you can\n" - " hardcode the desired paths on your system." - ); + NewsItem xdg_support( + version, "Support for XDG Base Directory Specification", "", + " The XDG Base Directory specification provides standard locations to store\n" + " application data, configuration, state, and cached data in order to keep $HOME\n" + " clutter-free. The locations are usually set to ~/.local/share, ~/.config,\n" + " ~/.local/state and ~/.cache respectively.", + " If taskrc is not found at '~/.taskrc', Taskwarrior will attempt to find it\n" + " at '$XDG_CONFIG_HOME/task/taskrc' (defaults to '~/.config/task/taskrc').", + "", + " This allows users to fully follow XDG Base Directory Spec by moving their taskrc:\n" + " $ mkdir $XDG_CONFIG_HOME/task\n" + " $ mv ~/.taskrc $XDG_CONFIG_HOME/task/taskrc\n\n" + " and further setting:\n" + " data.location=$XDG_DATA_HOME/task/\n" + " hooks.location=$XDG_CONFIG_HOME/task/hooks/\n\n" + " Solutions in the past required symlinks or more cumbersome configuration overrides.", + " If you configure your data.location and hooks.location as above, ensure\n" + " that the XDG_DATA_HOME and XDG_CONFIG_HOME environment variables are set,\n" + " otherwise they're going to expand to empty string. Alternatively you can\n" + " hardcode the desired paths on your system."); items.push_back(xdg_support); ///////////////////////////////////////////////////////////////////////////// // - Update holiday data - NewsItem holidata_2022 ( - version, - "Updated holiday data for 2022", - "", - "", - " Holiday data has been refreshed for 2022 and five more holiday locales\n" - " have been added: fr-CA, hu-HU, pt-BR, sk-SK and sv-FI.", - "", - " Refreshing the holiday data is part of every release. The addition of the new\n" - " locales allows us to better support users in those particular countries." - ); + NewsItem holidata_2022( + version, "Updated holiday data for 2022", "", "", + " Holiday data has been refreshed for 2022 and five more holiday locales\n" + " have been added: fr-CA, hu-HU, pt-BR, sk-SK and sv-FI.", + "", + " Refreshing the holiday data is part of every release. The addition of the new\n" + " locales allows us to better support users in those particular countries."); items.push_back(holidata_2022); } -void NewsItem::version3_0_0 (std::vector& items) { +void NewsItem::version3_0_0(std::vector& items) { Version version("3.0.0"); - NewsItem sync { - version, - /*title=*/"New data model and sync backend", - /*bg_title=*/"", - /*background=*/"", - /*punchline=*/ - "The sync functionality for Taskwarrior has been rewritten entirely, and no longer\n" - "supports taskserver/taskd. The most robust solution is a cloud-storage backend,\n" - "although a less-mature taskchampion-sync-server is also available. See `task-sync(5)`\n" - "For details. As part of this change, the on-disk storage format has also changed.\n", - /*update=*/ - "This is a breaking upgrade: you must export your task database from 2.x and re-import\n" - "it into 3.x. Hooks run during task import, so if you have any hooks defined,\n" - "temporarily disable them for this operation.\n\n" - "See https://taskwarrior.org/docs/upgrade-3/ for information on upgrading to Taskwarrior 3.0.", + NewsItem sync{ + version, + /*title=*/"New data model and sync backend", + /*bg_title=*/"", + /*background=*/"", + /*punchline=*/ + "The sync functionality for Taskwarrior has been rewritten entirely, and no longer\n" + "supports taskserver/taskd. The most robust solution is a cloud-storage backend,\n" + "although a less-mature taskchampion-sync-server is also available. See `task-sync(5)`\n" + "For details. As part of this change, the on-disk storage format has also changed.\n", + /*update=*/ + "This is a breaking upgrade: you must export your task database from 2.x and re-import\n" + "it into 3.x. Hooks run during task import, so if you have any hooks defined,\n" + "temporarily disable them for this operation.\n\n" + "See https://taskwarrior.org/docs/upgrade-3/ for information on upgrading to Taskwarrior " + "3.0.", }; items.push_back(sync); } -void NewsItem::version3_1_0 (std::vector& items) { +void NewsItem::version3_1_0(std::vector& items) { Version version("3.1.0"); - NewsItem sync { - version, - /*title=*/"Purging Tasks, Manually or Automatically", - /*bg_title=*/"", - /*background=*/"", - /*punchline=*/ - "Support for `task purge` has been restored, and new support added for automatically expiring\n" - "old tasks.\n\n" - /*update=*/ - "The `task purge` command removes tasks entirely, in contrast to `task delete` which merely sets\n" - "the task status to 'Deleted'. This functionality existed in versions 2.x but was temporarily\n" - "removed in 3.0.\n\n" - "The new `purge.on-sync` configuration parameter controls automatic purging of old tasks.\n" - "An old task is one with status 'Deleted' that has not been modified in 180 days. This\n" - "functionality is optional and not enabled by default." - }; + NewsItem sync{ + version, + /*title=*/"Purging Tasks, Manually or Automatically", + /*bg_title=*/"", + /*background=*/"", + /*punchline=*/ + "Support for `task purge` has been restored, and new support added for automatically " + "expiring\n" + "old tasks.\n\n" + /*update=*/ + "The `task purge` command removes tasks entirely, in contrast to `task delete` which merely " + "sets\n" + "the task status to 'Deleted'. This functionality existed in versions 2.x but was " + "temporarily\n" + "removed in 3.0.\n\n" + "The new `purge.on-sync` configuration parameter controls automatic purging of old tasks.\n" + "An old task is one with status 'Deleted' that has not been modified in 180 days. This\n" + "functionality is optional and not enabled by default."}; items.push_back(sync); } //////////////////////////////////////////////////////////////////////////////// -int CmdNews::execute (std::string& output) -{ - auto words = Context::getContext ().cli2.getWords (); - auto config = Context::getContext ().config; +int CmdNews::execute(std::string& output) { + auto words = Context::getContext().cli2.getWords(); + auto config = Context::getContext().config; // Supress compiler warning about unused argument output = ""; std::vector items = NewsItem::all(); - Version news_version(Context::getContext ().config.get ("news.version")); + Version news_version(Context::getContext().config.get("news.version")); Version current_version = Version::Current(); // 2.6.0 is the earliest version with news support. - if (!news_version.is_valid()) - news_version = Version("2.6.0"); + if (!news_version.is_valid()) news_version = Version("2.6.0"); - signal (SIGINT, signal_handler); + signal(SIGINT, signal_handler); // Remove items that have already been shown - items.erase ( - std::remove_if (items.begin (), items.end (), [&](const NewsItem& n){return n._version <= news_version;}), - items.end () - ); + items.erase(std::remove_if(items.begin(), items.end(), + [&](const NewsItem& n) { return n._version <= news_version; }), + items.end()); - - Color bold = Color ("bold"); - if (items.empty ()) { - std::cout << bold.colorize ("You are up to date!\n"); + Color bold = Color("bold"); + if (items.empty()) { + std::cout << bold.colorize("You are up to date!\n"); } else { // Print release notes - std::cout << bold.colorize (format ( - "\n" - "================================================\n" - "Taskwarrior {1} through {2} Release Highlights\n" - "================================================\n", - news_version, - current_version)); + std::cout << bold.colorize( + format("\n" + "================================================\n" + "Taskwarrior {1} through {2} Release Highlights\n" + "================================================\n", + news_version, current_version)); - for (unsigned short i=0; i < items.size (); i++) { - std::cout << format ("\n({1}/{2}) ", i+1, items.size ()); - items[i].render (); + for (unsigned short i = 0; i < items.size(); i++) { + std::cout << format("\n({1}/{2}) ", i + 1, items.size()); + items[i].render(); } std::cout << "Thank you for catching up on the new features!\n"; } - wait_for_enter (); + wait_for_enter(); // Display outro Datetime now; - Datetime beginning (2006, 11, 29); - Duration development_time = Duration (now - beginning); + Datetime beginning(2006, 11, 29); + Duration development_time = Duration(now - beginning); - Color underline = Color ("underline"); + Color underline = Color("underline"); std::stringstream outro; - outro << underline.colorize (bold.colorize ("Taskwarrior crowdfunding\n")); - outro << format ( - "Taskwarrior has been in development for {1} years but its survival\n" - "depends on your support!\n\n" - "Please consider joining our {2} fundraiser to help us fund maintenance\n" - "and development of new features:\n\n", - std::lround (static_cast(development_time.days ()) / 365.25), - now.year () - ); + outro << underline.colorize(bold.colorize("Taskwarrior crowdfunding\n")); + outro << format( + "Taskwarrior has been in development for {1} years but its survival\n" + "depends on your support!\n\n" + "Please consider joining our {2} fundraiser to help us fund maintenance\n" + "and development of new features:\n\n", + std::lround(static_cast(development_time.days()) / 365.25), now.year()); outro << bold.colorize(" https://github.com/sponsors/GothenburgBitFactory/\n\n"); outro << "Perks are available for our sponsors.\n"; - std::cout << outro.str (); + std::cout << outro.str(); // Set a mark in the config to remember which version's release notes were displayed - if (news_version != current_version) - { + if (news_version != current_version) { std::cout << "UPDATING\n"; - CmdConfig::setConfigVariable ("news.version", std::string(current_version), false); + CmdConfig::setConfigVariable("news.version", std::string(current_version), false); // Revert back to default signal handling after displaying the outro - signal (SIGINT, SIG_DFL); + signal(SIGINT, SIG_DFL); - std::string question = format ( - "\nWould you like to open Taskwarrior {1} fundraising campaign to read more?", - now.year () - ); + std::string question = format( + "\nWould you like to open Taskwarrior {1} fundraising campaign to read more?", now.year()); - std::vector options {"yes", "no"}; - std::vector matches; + std::vector options{"yes", "no"}; + std::vector matches; std::cout << question << " (YES/no) "; std::string answer; - std::getline (std::cin, answer); + std::getline(std::cin, answer); - if (std::cin.eof () || trim (answer).empty ()) + if (std::cin.eof() || trim(answer).empty()) answer = "yes"; else - lowerCase (trim (answer)); + lowerCase(trim(answer)); - autoComplete (answer, options, matches, 1); // Hard-coded 1. + autoComplete(answer, options, matches, 1); // Hard-coded 1. - if (matches.size () == 1 && matches[0] == "yes") -#if defined (DARWIN) - system ("open 'https://github.com/sponsors/GothenburgBitFactory/'"); + if (matches.size() == 1 && matches[0] == "yes") +#if defined(DARWIN) + system("open 'https://github.com/sponsors/GothenburgBitFactory/'"); #else - system ("xdg-open 'https://github.com/sponsors/GothenburgBitFactory/'"); + system("xdg-open 'https://github.com/sponsors/GothenburgBitFactory/'"); #endif std::cout << std::endl; - } - else - wait_for_enter (); // Do not display the outro and footnote at once + } else + wait_for_enter(); // Do not display the outro and footnote at once return 0; } diff --git a/src/commands/CmdNews.h b/src/commands/CmdNews.h index beee1af1e..7423954f7 100644 --- a/src/commands/CmdNews.h +++ b/src/commands/CmdNews.h @@ -27,14 +27,15 @@ #ifndef INCLUDED_CMDNEWS #define INCLUDED_CMDNEWS -#include -#include #include #include +#include #include +#include + class NewsItem { -public: + public: Version _version; std::string _title; std::string _bg_title; @@ -44,31 +45,23 @@ public: std::string _reasoning; std::string _actions; - void render (); + void render(); static std::vector all(); - static void version2_6_0 (std::vector&); - static void version3_0_0 (std::vector&); - static void version3_1_0 (std::vector&); + static void version2_6_0(std::vector&); + static void version3_0_0(std::vector&); + static void version3_1_0(std::vector&); -private: - NewsItem ( - Version, - const std::string&, - const std::string& = "", - const std::string& = "", - const std::string& = "", - const std::string& = "", - const std::string& = "", - const std::string& = "" - ); + private: + NewsItem(Version, const std::string&, const std::string& = "", const std::string& = "", + const std::string& = "", const std::string& = "", const std::string& = "", + const std::string& = ""); }; -class CmdNews : public Command -{ -public: - CmdNews (); - int execute (std::string&); +class CmdNews : public Command { + public: + CmdNews(); + int execute(std::string&); }; #endif diff --git a/src/commands/CmdPrepend.cpp b/src/commands/CmdPrepend.cpp index 25a307c49..79d67a881 100644 --- a/src/commands/CmdPrepend.cpp +++ b/src/commands/CmdPrepend.cpp @@ -28,111 +28,100 @@ // cmake.h include header must come first #include -#include #include #include -#include #include #include +#include + +#include //////////////////////////////////////////////////////////////////////////////// -CmdPrepend::CmdPrepend () -{ - _keyword = "prepend"; - _usage = "task prepend "; - _description = "Prepends text to an existing task description"; - _read_only = false; - _displays_id = false; - _needs_gc = false; - _uses_context = true; - _accepts_filter = true; +CmdPrepend::CmdPrepend() { + _keyword = "prepend"; + _usage = "task prepend "; + _description = "Prepends text to an existing task description"; + _read_only = false; + _displays_id = false; + _needs_gc = false; + _uses_context = true; + _accepts_filter = true; _accepts_modifications = true; _accepts_miscellaneous = false; - _category = Command::Category::operation; + _category = Command::Category::operation; } //////////////////////////////////////////////////////////////////////////////// -int CmdPrepend::execute (std::string&) -{ +int CmdPrepend::execute(std::string&) { int rc = 0; int count = 0; // Apply filter. Filter filter; - std::vector filtered; - filter.subset (filtered); - if (filtered.size () == 0) - { - Context::getContext ().footnote ("No tasks specified."); + std::vector filtered; + filter.subset(filtered); + if (filtered.size() == 0) { + Context::getContext().footnote("No tasks specified."); return 1; } // TODO Complain when no modifications are specified. // Accumulated project change notifications. - std::map projectChanges; + std::map projectChanges; - if(filtered.size() > 1) { + if (filtered.size() > 1) { feedback_affected("This command will alter {1} tasks.", filtered.size()); } - for (auto& task : filtered) - { - Task before (task); + for (auto& task : filtered) { + Task before(task); // Prepend to the specified task. - std::string question = format ("Prepend to task {1} '{2}'?", - task.identifier (true), - task.get ("description")); + std::string question = + format("Prepend to task {1} '{2}'?", task.identifier(true), task.get("description")); - task.modify (Task::modPrepend, true); + task.modify(Task::modPrepend, true); - if (permission (before.diff (task) + question, filtered.size ())) - { - Context::getContext ().tdb2.modify (task); + if (permission(before.diff(task) + question, filtered.size())) { + Context::getContext().tdb2.modify(task); ++count; - feedback_affected ("Prepending to task {1} '{2}'.", task); - if (Context::getContext ().verbose ("project")) - projectChanges[task.get ("project")] = onProjectChange (task, false); + feedback_affected("Prepending to task {1} '{2}'.", task); + if (Context::getContext().verbose("project")) + projectChanges[task.get("project")] = onProjectChange(task, false); // Prepend to siblings. - if (task.has ("parent")) - { - if ((Context::getContext ().config.get ("recurrence.confirmation") == "prompt" - && confirm ("This is a recurring task. Do you want to prepend to all pending recurrences of this same task?")) || - Context::getContext ().config.getBoolean ("recurrence.confirmation")) - { - std::vector siblings = Context::getContext ().tdb2.siblings (task); - for (auto& sibling : siblings) - { - sibling.modify (Task::modPrepend, true); - Context::getContext ().tdb2.modify (sibling); + if (task.has("parent")) { + if ((Context::getContext().config.get("recurrence.confirmation") == "prompt" && + confirm("This is a recurring task. Do you want to prepend to all pending recurrences " + "of this same task?")) || + Context::getContext().config.getBoolean("recurrence.confirmation")) { + std::vector siblings = Context::getContext().tdb2.siblings(task); + for (auto& sibling : siblings) { + sibling.modify(Task::modPrepend, true); + Context::getContext().tdb2.modify(sibling); ++count; - feedback_affected ("Prepending to recurring task {1} '{2}'.", sibling); + feedback_affected("Prepending to recurring task {1} '{2}'.", sibling); } // Prepend to the parent Task parent; - Context::getContext ().tdb2.get (task.get ("parent"), parent); - parent.modify (Task::modPrepend, true); - Context::getContext ().tdb2.modify (parent); + Context::getContext().tdb2.get(task.get("parent"), parent); + parent.modify(Task::modPrepend, true); + Context::getContext().tdb2.modify(parent); } } - } - else - { + } else { std::cout << "Task not prepended.\n"; rc = 1; - if (_permission_quit) - break; + if (_permission_quit) break; } } // Now list the project changes. for (auto& change : projectChanges) - if (change.first != "") - Context::getContext ().footnote (change.second); + if (change.first != "") Context::getContext().footnote(change.second); - feedback_affected (count == 1 ? "Prepended {1} task." : "Prepended {1} tasks.", count); + feedback_affected(count == 1 ? "Prepended {1} task." : "Prepended {1} tasks.", count); return rc; } diff --git a/src/commands/CmdPrepend.h b/src/commands/CmdPrepend.h index 2e07a6253..4fb499f96 100644 --- a/src/commands/CmdPrepend.h +++ b/src/commands/CmdPrepend.h @@ -27,14 +27,14 @@ #ifndef INCLUDED_CMDPREPEND #define INCLUDED_CMDPREPEND -#include #include -class CmdPrepend : public Command -{ -public: - CmdPrepend (); - int execute (std::string&); +#include + +class CmdPrepend : public Command { + public: + CmdPrepend(); + int execute(std::string&); }; #endif diff --git a/src/commands/CmdProjects.cpp b/src/commands/CmdProjects.cpp index 97d668f80..dc98f8af3 100644 --- a/src/commands/CmdProjects.cpp +++ b/src/commands/CmdProjects.cpp @@ -28,172 +28,148 @@ // cmake.h include header must come first #include -#include -#include #include #include #include #include -#include #include +#include + +#include #include +#include //////////////////////////////////////////////////////////////////////////////// -CmdProjects::CmdProjects () -{ - _keyword = "projects"; - _usage = "task projects"; - _description = "Shows all project names used"; - _read_only = true; - _displays_id = false; - _needs_gc = true; - _uses_context = true; - _accepts_filter = true; +CmdProjects::CmdProjects() { + _keyword = "projects"; + _usage = "task projects"; + _description = "Shows all project names used"; + _read_only = true; + _displays_id = false; + _needs_gc = true; + _uses_context = true; + _accepts_filter = true; _accepts_modifications = false; _accepts_miscellaneous = false; - _category = Command::Category::metadata; + _category = Command::Category::metadata; } //////////////////////////////////////////////////////////////////////////////// -int CmdProjects::execute (std::string& output) -{ +int CmdProjects::execute(std::string& output) { int rc = 0; // Get all the tasks. - handleUntil (); - handleRecurrence (); - auto tasks = Context::getContext ().tdb2.pending_tasks (); + handleUntil(); + handleRecurrence(); + auto tasks = Context::getContext().tdb2.pending_tasks(); - if (Context::getContext ().config.getBoolean ("list.all.projects")) - for (auto& task : Context::getContext ().tdb2.completed_tasks ()) - tasks.push_back (task); + if (Context::getContext().config.getBoolean("list.all.projects")) + for (auto& task : Context::getContext().tdb2.completed_tasks()) tasks.push_back(task); // Apply the filter. Filter filter; - std::vector filtered; - filter.subset (tasks, filtered); - int quantity = filtered.size (); + std::vector filtered; + filter.subset(tasks, filtered); + int quantity = filtered.size(); std::stringstream out; // Scan all the tasks for their project name, building a map using project // names as keys. - std::map unique; + std::map unique; bool no_project = false; std::string project; - for (auto& task : filtered) - { - if (task.getStatus () == Task::deleted) - { + for (auto& task : filtered) { + if (task.getStatus() == Task::deleted) { --quantity; continue; } // Increase the count for the project the task belongs to and all // its super-projects - project = task.get ("project"); + project = task.get("project"); - std::vector projects = extractParents (project); - projects.push_back (project); + std::vector projects = extractParents(project); + projects.push_back(project); - for (auto& parent : projects) - unique[parent] += 1; + for (auto& parent : projects) unique[parent] += 1; - if (project == "") - no_project = true; + if (project == "") no_project = true; } - if (unique.size ()) - { + if (unique.size()) { // Render a list of project names from the map. Table view; - view.width (Context::getContext ().getWidth ()); - view.add ("Project"); - view.add ("Tasks", false); - setHeaderUnderline (view); + view.width(Context::getContext().getWidth()); + view.add("Project"); + view.add("Tasks", false); + setHeaderUnderline(view); // create sorted list of table entries - std::list > sorted_view; - sort_projects (sorted_view, unique); + std::list> sorted_view; + sort_projects(sorted_view, unique); // construct view from sorted list - for (auto& item: sorted_view) - { - int row = view.addRow (); - view.set (row, 0, (item.first == "" - ? "(none)" - : indentProject (item.first, " ", '.'))); - view.set (row, 1, item.second); + for (auto& item : sorted_view) { + int row = view.addRow(); + view.set(row, 0, (item.first == "" ? "(none)" : indentProject(item.first, " ", '.'))); + view.set(row, 1, item.second); } - int number_projects = unique.size (); - if (no_project) - --number_projects; + int number_projects = unique.size(); + if (no_project) --number_projects; - out << optionalBlankLine () - << view.render () - << optionalBlankLine () - << (number_projects == 1 - ? format ("{1} project", number_projects) - : format ("{1} projects", number_projects)) - << ' ' - << (quantity == 1 - ? format ("({1} task)", quantity) - : format ("({1} tasks)", quantity)) + out << optionalBlankLine() << view.render() << optionalBlankLine() + << (number_projects == 1 ? format("{1} project", number_projects) + : format("{1} projects", number_projects)) + << ' ' << (quantity == 1 ? format("({1} task)", quantity) : format("({1} tasks)", quantity)) << '\n'; - } - else - { + } else { out << "No projects.\n"; rc = 1; } - output = out.str (); + output = out.str(); return rc; } //////////////////////////////////////////////////////////////////////////////// -CmdCompletionProjects::CmdCompletionProjects () -{ - _keyword = "_projects"; - _usage = "task _projects"; - _description = "Shows only a list of all project names used"; - _read_only = true; - _displays_id = false; - _needs_gc = true; - _uses_context = false; - _accepts_filter = true; +CmdCompletionProjects::CmdCompletionProjects() { + _keyword = "_projects"; + _usage = "task _projects"; + _description = "Shows only a list of all project names used"; + _read_only = true; + _displays_id = false; + _needs_gc = true; + _uses_context = false; + _accepts_filter = true; _accepts_modifications = false; _accepts_miscellaneous = false; - _category = Command::Category::internal; + _category = Command::Category::internal; } //////////////////////////////////////////////////////////////////////////////// -int CmdCompletionProjects::execute (std::string& output) -{ +int CmdCompletionProjects::execute(std::string& output) { // Get all the tasks. - handleUntil (); - handleRecurrence (); - auto tasks = Context::getContext ().tdb2.pending_tasks (); + handleUntil(); + handleRecurrence(); + auto tasks = Context::getContext().tdb2.pending_tasks(); - if (Context::getContext ().config.getBoolean ("list.all.projects")) - for (auto& task : Context::getContext ().tdb2.completed_tasks ()) - tasks.push_back (task); + if (Context::getContext().config.getBoolean("list.all.projects")) + for (auto& task : Context::getContext().tdb2.completed_tasks()) tasks.push_back(task); // Apply the filter. Filter filter; - std::vector filtered; - filter.subset (tasks, filtered); + std::vector filtered; + filter.subset(tasks, filtered); // Scan all the tasks for their project name, building a map using project // names as keys. - std::map unique; - for (auto& task : filtered) - unique[task.get ("project")] = 0; + std::map unique; + for (auto& task : filtered) unique[task.get("project")] = 0; for (auto& project : unique) - if (project.first.length ()) - output += project.first + '\n'; + if (project.first.length()) output += project.first + '\n'; return 0; } diff --git a/src/commands/CmdProjects.h b/src/commands/CmdProjects.h index 206d3a664..180db8f8b 100644 --- a/src/commands/CmdProjects.h +++ b/src/commands/CmdProjects.h @@ -27,21 +27,20 @@ #ifndef INCLUDED_CMDPROJECTS #define INCLUDED_CMDPROJECTS -#include #include -class CmdProjects : public Command -{ -public: - CmdProjects (); - int execute (std::string&); +#include + +class CmdProjects : public Command { + public: + CmdProjects(); + int execute(std::string&); }; -class CmdCompletionProjects : public Command -{ -public: - CmdCompletionProjects (); - int execute (std::string&); +class CmdCompletionProjects : public Command { + public: + CmdCompletionProjects(); + int execute(std::string&); }; #endif diff --git a/src/commands/CmdPurge.cpp b/src/commands/CmdPurge.cpp index cee795820..5bb309ddb 100644 --- a/src/commands/CmdPurge.cpp +++ b/src/commands/CmdPurge.cpp @@ -30,155 +30,138 @@ #include #include #include -#include #include +#include #include //////////////////////////////////////////////////////////////////////////////// -CmdPurge::CmdPurge () -{ - _keyword = "purge"; - _usage = "task purge"; - _description = "Removes the specified tasks from the data files. Causes permanent loss of data."; - _read_only = false; - _displays_id = false; - _needs_confirm = true; - _needs_gc = true; - _uses_context = true; - _accepts_filter = true; +CmdPurge::CmdPurge() { + _keyword = "purge"; + _usage = "task purge"; + _description = "Removes the specified tasks from the data files. Causes permanent loss of data."; + _read_only = false; + _displays_id = false; + _needs_confirm = true; + _needs_gc = true; + _uses_context = true; + _accepts_filter = true; _accepts_modifications = false; _accepts_miscellaneous = false; - _category = Command::Category::operation; + _category = Command::Category::operation; } //////////////////////////////////////////////////////////////////////////////// // Purges the task, while taking care of: // - dependencies on this task // - child tasks -void CmdPurge::handleRelations (Task& task, std::vector& tasks) -{ - handleDeps (task); - handleChildren (task, tasks); +void CmdPurge::handleRelations(Task& task, std::vector& tasks) { + handleDeps(task); + handleChildren(task, tasks); tasks.push_back(task); } //////////////////////////////////////////////////////////////////////////////// // Makes sure that any task having the dependency on the task being purged // has that dependency removed, to preserve referential integrity. -void CmdPurge::handleDeps (Task& task) -{ - std::string uuid = task.get ("uuid"); +void CmdPurge::handleDeps(Task& task) { + std::string uuid = task.get("uuid"); - for (auto& blockedConst: Context::getContext ().tdb2.all_tasks ()) - { - Task& blocked = const_cast(blockedConst); - if (blocked.hasDependency (uuid)) - { - blocked.removeDependency (uuid); - Context::getContext ().tdb2.modify (blocked); - } - } + for (auto& blockedConst : Context::getContext().tdb2.all_tasks()) { + Task& blocked = const_cast(blockedConst); + if (blocked.hasDependency(uuid)) { + blocked.removeDependency(uuid); + Context::getContext().tdb2.modify(blocked); + } + } } //////////////////////////////////////////////////////////////////////////////// // Makes sure that with any recurrence parent are all the child tasks removed // as well. If user chooses not to, the whole command is aborted. -void CmdPurge::handleChildren (Task& task, std::vector& tasks) -{ +void CmdPurge::handleChildren(Task& task, std::vector& tasks) { // If this is not a recurrence parent, we have no job here - if (!task.has ("mask")) - return; + if (!task.has("mask")) return; - std::string uuid = task.get ("uuid"); + std::string uuid = task.get("uuid"); std::vector children; // Find all child tasks - for (auto& childConst: Context::getContext ().tdb2.all_tasks ()) - { - Task& child = const_cast (childConst); + for (auto& childConst : Context::getContext().tdb2.all_tasks()) { + Task& child = const_cast(childConst); - if (child.get ("parent") == uuid) - { - if (child.getStatus () != Task::deleted) + if (child.get("parent") == uuid) { + if (child.getStatus() != Task::deleted) // In case any child task is not deleted, bail out - throw format ("Task '{1}' is a recurrence template. Its child task {2} must be deleted before it can be purged.", - task.get ("description"), - child.identifier (true)); + throw format( + "Task '{1}' is a recurrence template. Its child task {2} must be deleted before it can " + "be purged.", + task.get("description"), child.identifier(true)); else - children.push_back (child); + children.push_back(child); } } // If there are no children, our job is done - if (children.empty ()) - return; + if (children.empty()) return; // Ask for confirmation to purge them, if needed - std::string question = format ("Task '{1}' is a recurrence template. All its {2} deleted children tasks will be purged as well. Continue?", - task.get ("description"), - children.size ()); + std::string question = format( + "Task '{1}' is a recurrence template. All its {2} deleted children tasks will be purged as " + "well. Continue?", + task.get("description"), children.size()); - if (Context::getContext ().config.getBoolean ("recurrence.confirmation") || - (Context::getContext ().config.get ("recurrence.confirmation") == "prompt" - && confirm (question))) - { - for (auto& child: children) - handleRelations (child, tasks); - } - else - throw std::string ("Purge operation aborted."); + if (Context::getContext().config.getBoolean("recurrence.confirmation") || + (Context::getContext().config.get("recurrence.confirmation") == "prompt" && + confirm(question))) { + for (auto& child : children) handleRelations(child, tasks); + } else + throw std::string("Purge operation aborted."); } - //////////////////////////////////////////////////////////////////////////////// -int CmdPurge::execute (std::string&) -{ +int CmdPurge::execute(std::string&) { int rc = 0; std::vector tasks; bool matched_deleted = false; Filter filter; - std::vector filtered; + std::vector filtered; // Apply filter. - filter.subset (filtered); - if (filtered.size () == 0) - { - Context::getContext ().footnote ("No tasks specified."); + filter.subset(filtered); + if (filtered.size() == 0) { + Context::getContext().footnote("No tasks specified."); return 1; } - for (auto& task : filtered) - { + for (auto& task : filtered) { // Allow purging of deleted tasks only. Hence no need to deal with: // - unblocked tasks notifications (deleted tasks are not blocking) // - project changes (deleted tasks not included in progress) // It also has the nice property of being explicit - users need to // mark tasks as deleted before purging. - if (task.getStatus () == Task::deleted) - { + if (task.getStatus() == Task::deleted) { // Mark that at least one deleted task matched the filter matched_deleted = true; std::string question; - question = format ("Permanently remove task {1} '{2}'?", - task.identifier (true), - task.get ("description")); + question = format("Permanently remove task {1} '{2}'?", task.identifier(true), + task.get("description")); - if (permission (question, filtered.size ())) - handleRelations (task, tasks); + if (permission(question, filtered.size())) handleRelations(task, tasks); } } // Now that any exceptions are handled, actually purge the tasks. - for (auto& task: tasks) { - Context::getContext ().tdb2.purge (task); + for (auto& task : tasks) { + Context::getContext().tdb2.purge(task); } - if (filtered.size () > 0 and ! matched_deleted) - Context::getContext ().footnote ("No deleted tasks specified. Maybe you forgot to delete tasks first?"); + if (filtered.size() > 0 and !matched_deleted) + Context::getContext().footnote( + "No deleted tasks specified. Maybe you forgot to delete tasks first?"); - feedback_affected (tasks.size() == 1 ? "Purged {1} task." : "Purged {1} tasks.", tasks.size()); + feedback_affected(tasks.size() == 1 ? "Purged {1} task." : "Purged {1} tasks.", tasks.size()); return rc; } diff --git a/src/commands/CmdPurge.h b/src/commands/CmdPurge.h index c97fbf970..f46137745 100644 --- a/src/commands/CmdPurge.h +++ b/src/commands/CmdPurge.h @@ -27,19 +27,20 @@ #ifndef INCLUDED_CMDPURGE #define INCLUDED_CMDPURGE -#include -#include #include -class CmdPurge : public Command -{ -private: - void handleRelations (Task& task, std::vector& tasks); - void handleChildren (Task& task, std::vector& tasks); - void handleDeps (Task& task); -public: - CmdPurge (); - int execute (std::string&); +#include +#include + +class CmdPurge : public Command { + private: + void handleRelations(Task& task, std::vector& tasks); + void handleChildren(Task& task, std::vector& tasks); + void handleDeps(Task& task); + + public: + CmdPurge(); + int execute(std::string&); }; #endif diff --git a/src/commands/CmdReports.cpp b/src/commands/CmdReports.cpp index e8bfa80dc..1b2d83eed 100644 --- a/src/commands/CmdReports.cpp +++ b/src/commands/CmdReports.cpp @@ -28,81 +28,74 @@ // cmake.h include header must come first #include -#include #include #include #include #include +#include + //////////////////////////////////////////////////////////////////////////////// -CmdReports::CmdReports () -{ - _keyword = "reports"; - _usage = "task reports"; - _description = "Lists all supported reports"; - _read_only = true; - _displays_id = false; - _needs_gc = false; - _uses_context = false; - _accepts_filter = false; +CmdReports::CmdReports() { + _keyword = "reports"; + _usage = "task reports"; + _description = "Lists all supported reports"; + _read_only = true; + _displays_id = false; + _needs_gc = false; + _uses_context = false; + _accepts_filter = false; _accepts_modifications = false; _accepts_miscellaneous = false; - _category = Command::Category::config; + _category = Command::Category::config; } //////////////////////////////////////////////////////////////////////////////// -int CmdReports::execute (std::string& output) -{ - std::vector reports; +int CmdReports::execute(std::string& output) { + std::vector reports; // Add custom reports. - for (auto& i : Context::getContext ().config) - { - if (i.first.substr (0, 7) == "report.") - { - std::string report = i.first.substr (7); - auto columns = report.find (".columns"); - if (columns != std::string::npos) - reports.push_back (report.substr (0, columns)); + for (auto& i : Context::getContext().config) { + if (i.first.substr(0, 7) == "report.") { + std::string report = i.first.substr(7); + auto columns = report.find(".columns"); + if (columns != std::string::npos) reports.push_back(report.substr(0, columns)); } } // Add known reports. - reports.push_back ("burndown.daily"); - reports.push_back ("burndown.monthly"); - reports.push_back ("burndown.weekly"); - reports.push_back ("ghistory.annual"); - reports.push_back ("ghistory.monthly"); - reports.push_back ("history.annual"); - reports.push_back ("history.monthly"); - reports.push_back ("information"); - reports.push_back ("projects"); - reports.push_back ("summary"); - reports.push_back ("tags"); + reports.push_back("burndown.daily"); + reports.push_back("burndown.monthly"); + reports.push_back("burndown.weekly"); + reports.push_back("ghistory.annual"); + reports.push_back("ghistory.monthly"); + reports.push_back("history.annual"); + reports.push_back("history.monthly"); + reports.push_back("information"); + reports.push_back("projects"); + reports.push_back("summary"); + reports.push_back("tags"); - std::sort (reports.begin (), reports.end ()); + std::sort(reports.begin(), reports.end()); // Compose the output. std::stringstream out; Table view; - view.width (Context::getContext ().getWidth ()); - view.add ("Report"); - view.add ("Description"); - setHeaderUnderline (view); + view.width(Context::getContext().getWidth()); + view.add("Report"); + view.add("Description"); + setHeaderUnderline(view); - for (auto& report : reports) - { - int row = view.addRow (); - view.set (row, 0, report); - view.set (row, 1, Context::getContext ().commands[report]->description ()); + for (auto& report : reports) { + int row = view.addRow(); + view.set(row, 0, report); + view.set(row, 1, Context::getContext().commands[report]->description()); } - out << optionalBlankLine () - << view.render () - << optionalBlankLine () - << format ("{1} reports\n", reports.size ()); + out << optionalBlankLine() << view.render() << optionalBlankLine() + << format("{1} reports\n", reports.size()); - output = out.str (); + output = out.str(); return 0; } diff --git a/src/commands/CmdReports.h b/src/commands/CmdReports.h index 0dc74e4fc..893558d3a 100644 --- a/src/commands/CmdReports.h +++ b/src/commands/CmdReports.h @@ -27,14 +27,14 @@ #ifndef INCLUDED_CMDREPORTS #define INCLUDED_CMDREPORTS -#include #include -class CmdReports : public Command -{ -public: - CmdReports (); - int execute (std::string&); +#include + +class CmdReports : public Command { + public: + CmdReports(); + int execute(std::string&); }; #endif diff --git a/src/commands/CmdShow.cpp b/src/commands/CmdShow.cpp index 4bb797d71..bacc5c464 100644 --- a/src/commands/CmdShow.cpp +++ b/src/commands/CmdShow.cpp @@ -28,257 +28,245 @@ // cmake.h include header must come first #include -#include -#include -#include -#include -#include #include #include #include +#include +#include #include +#include +#include +#include + #define STRING_CMD_SHOW_DIFFER_COLOR "These are highlighted in {1} above." -#define STRING_CMD_SHOW_CONFIG_ERROR "Configuration error: {1} contains an unrecognized value '{2}'." +#define STRING_CMD_SHOW_CONFIG_ERROR \ + "Configuration error: {1} contains an unrecognized value '{2}'." extern std::string configurationDefaults; //////////////////////////////////////////////////////////////////////////////// -CmdShow::CmdShow () -{ - _keyword = "show"; - _usage = "task show [all | substring]"; - _description = "Shows all configuration variables or subset"; - _read_only = true; - _displays_id = false; - _needs_gc = false; - _uses_context = false; - _accepts_filter = false; +CmdShow::CmdShow() { + _keyword = "show"; + _usage = "task show [all | substring]"; + _description = "Shows all configuration variables or subset"; + _read_only = true; + _displays_id = false; + _needs_gc = false; + _uses_context = false; + _accepts_filter = false; _accepts_modifications = false; _accepts_miscellaneous = true; - _category = Command::Category::config; + _category = Command::Category::config; } //////////////////////////////////////////////////////////////////////////////// -int CmdShow::execute (std::string& output) -{ +int CmdShow::execute(std::string& output) { int rc = 0; std::stringstream out; // Obtain the arguments from the description. That way, things like '--' // have already been handled. - std::vector words = Context::getContext ().cli2.getWords (); - if (words.size () > 1) - throw std::string ("You can only specify 'all' or a search string."); + std::vector words = Context::getContext().cli2.getWords(); + if (words.size() > 1) throw std::string("You can only specify 'all' or a search string."); - int width = Context::getContext ().getWidth (); + int width = Context::getContext().getWidth(); // Complain about configuration variables that are not recognized. // These are the regular configuration variables. // Note that there is a leading and trailing space, to make it easier to // search for whole words. std::string recognized = - " abbreviation.minimum" - " active.indicator" - " allow.empty.filter" - " avoidlastcolumn" - " bulk" - " calendar.details" - " calendar.details.report" - " calendar.holidays" - " calendar.legend" - " calendar.monthsperline" - " calendar.offset" - " calendar.offset.value" - " color" - " color.active" - " color.alternate" - " color.blocked" - " color.blocking" - " color.burndown.done" - " color.burndown.pending" - " color.burndown.started" - " color.calendar.due" - " color.calendar.due.today" - " color.calendar.holiday" - " color.calendar.scheduled" - " color.calendar.overdue" - " color.calendar.today" - " color.calendar.weekend" - " color.calendar.weeknumber" - " color.completed" - " color.debug" - " color.deleted" - " color.due" - " color.due.today" - " color.warning" - " color.error" - " color.footnote" - " color.header" - " color.history.add" - " color.history.delete" - " color.history.done" - " color.label" - " color.label.sort" - " color.overdue" - " color.recurring" - " color.scheduled" - " color.summary.background" - " color.summary.bar" - " color.sync.added" - " color.sync.changed" - " color.sync.rejected" - " color.tagged" - " color.undo.after" - " color.undo.before" - " color.until" - " column.padding" - " complete.all.tags" - " confirmation" - " context" - " data.location" - " dateformat" - " dateformat.annotation" - " dateformat.edit" - " dateformat.holiday" - " dateformat.info" - " dateformat.report" - " date.iso" - " debug" - " debug.hooks" - " debug.parser" - " default.command" - " default.due" - " default.project" - " default.scheduled" - " defaultheight" - " defaultwidth" - " default.timesheet.filter" - " dependency.confirmation" - " dependency.indicator" - " dependency.reminder" - " detection" - " displayweeknumber" - " due" - " editor" - " exit.on.missing.db" - " purge.on-sync" - " expressions" - " fontunderline" - " gc" - " hooks" - " hooks.location" - " hyphenate" - " indent.annotation" - " indent.report" - " journal.info" - " journal.time" - " journal.time.start.annotation" - " journal.time.stop.annotation" - " json.array" - " limit" - " list.all.projects" - " list.all.tags" - " nag" - " news.version" - " obfuscate" - " print.empty.columns" - " recurrence" - " recurrence.confirmation" - " recurrence.indicator" - " recurrence.limit" - " regex" - " reserved.lines" - " row.padding" - " rule.color.merge" - " rule.precedence.color" - " search.case.sensitive" - " sugar" - " summary.all.projects" - " sync.local.server_dir" - " sync.gcp.credential_path" - " sync.gcp.bucket" - " sync.server.client_id" - " sync.encryption_secret" - " sync.server.url" - " sync.server.origin" - " tag.indicator" - " undo.style" - " urgency.active.coefficient" - " urgency.scheduled.coefficient" - " urgency.annotations.coefficient" - " urgency.blocked.coefficient" - " urgency.blocking.coefficient" - " urgency.due.coefficient" - " urgency.project.coefficient" - " urgency.tags.coefficient" - " urgency.waiting.coefficient" - " urgency.age.coefficient" - " urgency.age.max" - " urgency.inherit" - " verbose" - " weekstart" - " xterm.title" - " "; + " abbreviation.minimum" + " active.indicator" + " allow.empty.filter" + " avoidlastcolumn" + " bulk" + " calendar.details" + " calendar.details.report" + " calendar.holidays" + " calendar.legend" + " calendar.monthsperline" + " calendar.offset" + " calendar.offset.value" + " color" + " color.active" + " color.alternate" + " color.blocked" + " color.blocking" + " color.burndown.done" + " color.burndown.pending" + " color.burndown.started" + " color.calendar.due" + " color.calendar.due.today" + " color.calendar.holiday" + " color.calendar.scheduled" + " color.calendar.overdue" + " color.calendar.today" + " color.calendar.weekend" + " color.calendar.weeknumber" + " color.completed" + " color.debug" + " color.deleted" + " color.due" + " color.due.today" + " color.warning" + " color.error" + " color.footnote" + " color.header" + " color.history.add" + " color.history.delete" + " color.history.done" + " color.label" + " color.label.sort" + " color.overdue" + " color.recurring" + " color.scheduled" + " color.summary.background" + " color.summary.bar" + " color.sync.added" + " color.sync.changed" + " color.sync.rejected" + " color.tagged" + " color.undo.after" + " color.undo.before" + " color.until" + " column.padding" + " complete.all.tags" + " confirmation" + " context" + " data.location" + " dateformat" + " dateformat.annotation" + " dateformat.edit" + " dateformat.holiday" + " dateformat.info" + " dateformat.report" + " date.iso" + " debug" + " debug.hooks" + " debug.parser" + " default.command" + " default.due" + " default.project" + " default.scheduled" + " defaultheight" + " defaultwidth" + " default.timesheet.filter" + " dependency.confirmation" + " dependency.indicator" + " dependency.reminder" + " detection" + " displayweeknumber" + " due" + " editor" + " exit.on.missing.db" + " purge.on-sync" + " expressions" + " fontunderline" + " gc" + " hooks" + " hooks.location" + " hyphenate" + " indent.annotation" + " indent.report" + " journal.info" + " journal.time" + " journal.time.start.annotation" + " journal.time.stop.annotation" + " json.array" + " limit" + " list.all.projects" + " list.all.tags" + " nag" + " news.version" + " obfuscate" + " print.empty.columns" + " recurrence" + " recurrence.confirmation" + " recurrence.indicator" + " recurrence.limit" + " regex" + " reserved.lines" + " row.padding" + " rule.color.merge" + " rule.precedence.color" + " search.case.sensitive" + " sugar" + " summary.all.projects" + " sync.local.server_dir" + " sync.gcp.credential_path" + " sync.gcp.bucket" + " sync.server.client_id" + " sync.encryption_secret" + " sync.server.url" + " sync.server.origin" + " tag.indicator" + " undo.style" + " urgency.active.coefficient" + " urgency.scheduled.coefficient" + " urgency.annotations.coefficient" + " urgency.blocked.coefficient" + " urgency.blocking.coefficient" + " urgency.due.coefficient" + " urgency.project.coefficient" + " urgency.tags.coefficient" + " urgency.waiting.coefficient" + " urgency.age.coefficient" + " urgency.age.max" + " urgency.inherit" + " verbose" + " weekstart" + " xterm.title" + " "; // This configuration variable is supported, but not documented. It exists // so that unit tests can force color to be on even when the output from task // is redirected to a file, or stdout is not a tty. recognized += "_forcecolor "; - std::vector unrecognized; - for (auto& i : Context::getContext ().config) - { + std::vector unrecognized; + for (auto& i : Context::getContext().config) { // Disallow partial matches by tacking a leading and trailing space on each // variable name. std::string pattern = ' ' + i.first + ' '; - if (recognized.find (pattern) == std::string::npos) - { + if (recognized.find(pattern) == std::string::npos) { // These are special configuration variables, because their name is // dynamic. - if (i.first.substr (0, 14) != "color.keyword." && - i.first.substr (0, 14) != "color.project." && - i.first.substr (0, 10) != "color.tag." && - i.first.substr (0, 10) != "color.uda." && - i.first.substr (0, 8) != "context." && - i.first.substr (0, 8) != "holiday." && - i.first.substr (0, 7) != "report." && - i.first.substr (0, 6) != "alias." && - i.first.substr (0, 5) != "hook." && - i.first.substr (0, 4) != "uda." && - i.first.substr (0, 8) != "default." && - i.first.substr (0, 21) != "urgency.user.project." && - i.first.substr (0, 17) != "urgency.user.tag." && - i.first.substr (0, 21) != "urgency.user.keyword." && - i.first.substr (0, 12) != "urgency.uda.") - { - unrecognized.push_back (i.first); + if (i.first.substr(0, 14) != "color.keyword." && i.first.substr(0, 14) != "color.project." && + i.first.substr(0, 10) != "color.tag." && i.first.substr(0, 10) != "color.uda." && + i.first.substr(0, 8) != "context." && i.first.substr(0, 8) != "holiday." && + i.first.substr(0, 7) != "report." && i.first.substr(0, 6) != "alias." && + i.first.substr(0, 5) != "hook." && i.first.substr(0, 4) != "uda." && + i.first.substr(0, 8) != "default." && i.first.substr(0, 21) != "urgency.user.project." && + i.first.substr(0, 17) != "urgency.user.tag." && + i.first.substr(0, 21) != "urgency.user.keyword." && + i.first.substr(0, 12) != "urgency.uda.") { + unrecognized.push_back(i.first); } } } // Find all the values that match the defaults, for highlighting. - std::vector default_values; + std::vector default_values; Configuration default_config; - default_config.parse (configurationDefaults); + default_config.parse(configurationDefaults); - for (auto& i : Context::getContext ().config) - if (i.second != default_config.get (i.first)) - default_values.push_back (i.first); + for (auto& i : Context::getContext().config) + if (i.second != default_config.get(i.first)) default_values.push_back(i.first); // Create output view. Table view; - view.width (width); - view.add ("Config Variable"); - view.add ("Value"); - setHeaderUnderline (view); + view.width(width); + view.add("Config Variable"); + view.add("Value"); + setHeaderUnderline(view); Color error; Color warning; - if (Context::getContext ().color ()) - { - error = Color (Context::getContext ().config.get ("color.error")); - warning = Color (Context::getContext ().config.get ("color.warning")); + if (Context::getContext().color()) { + error = Color(Context::getContext().config.get("color.error")); + warning = Color(Context::getContext().config.get("color.warning")); } bool issue_error = false; @@ -287,144 +275,119 @@ int CmdShow::execute (std::string& output) std::string section; // Look for the first plausible argument which could be a pattern - if (words.size ()) - section = words[0]; + if (words.size()) section = words[0]; - if (section == "all") - section = ""; + if (section == "all") section = ""; std::string::size_type loc; - for (auto& i : Context::getContext ().config) - { - loc = i.first.find (section, 0); - if (loc != std::string::npos) - { + for (auto& i : Context::getContext().config) { + loc = i.first.find(section, 0); + if (loc != std::string::npos) { // Look for unrecognized. Color color; - if (std::find (unrecognized.begin (), unrecognized.end (), i.first) != unrecognized.end ()) - { + if (std::find(unrecognized.begin(), unrecognized.end(), i.first) != unrecognized.end()) { issue_error = true; color = error; - } - else if (std::find (default_values.begin (), default_values.end (), i.first) != default_values.end ()) - { + } else if (std::find(default_values.begin(), default_values.end(), i.first) != + default_values.end()) { issue_warning = true; color = warning; } std::string value = i.second; - int row = view.addRow (); - view.set (row, 0, i.first, color); - view.set (row, 1, value, color); + int row = view.addRow(); + view.set(row, 0, i.first, color); + view.set(row, 1, value, color); - if (default_config[i.first] != value && - default_config[i.first] != "") - { - row = view.addRow (); - view.set (row, 0, std::string (" ") + "Default value", color); - view.set (row, 1, default_config[i.first], color); + if (default_config[i.first] != value && default_config[i.first] != "") { + row = view.addRow(); + view.set(row, 0, std::string(" ") + "Default value", color); + view.set(row, 1, default_config[i.first], color); } } } out << '\n' - << view.render () - << (view.rows () == 0 ? "No matching configuration variables." : "") - << (view.rows () == 0 ? "\n\n" : "\n"); + << view.render() << (view.rows() == 0 ? "No matching configuration variables." : "") + << (view.rows() == 0 ? "\n\n" : "\n"); - if (issue_warning) - { + if (issue_warning) { out << "Some of your .taskrc variables differ from the default values.\n"; - if (Context::getContext ().color () && warning.nontrivial ()) - out << " " - << format (STRING_CMD_SHOW_DIFFER_COLOR, warning.colorize ("color")) - << "\n\n"; + if (Context::getContext().color() && warning.nontrivial()) + out << " " << format(STRING_CMD_SHOW_DIFFER_COLOR, warning.colorize("color")) << "\n\n"; } // Display the unrecognized variables. - if (issue_error) - { + if (issue_error) { out << "Your .taskrc file contains these unrecognized variables:\n"; - for (auto& i : unrecognized) - out << " " << i << '\n'; + for (auto& i : unrecognized) out << " " << i << '\n'; - if (Context::getContext ().color () && error.nontrivial ()) - out << '\n' << format (STRING_CMD_SHOW_DIFFER_COLOR, error.colorize ("color")); + if (Context::getContext().color() && error.nontrivial()) + out << '\n' << format(STRING_CMD_SHOW_DIFFER_COLOR, error.colorize("color")); out << "\n\n"; } - out << legacyCheckForDeprecatedVariables (); - out << legacyCheckForDeprecatedColumns (); + out << legacyCheckForDeprecatedVariables(); + out << legacyCheckForDeprecatedColumns(); // TODO Check for referenced but missing theme files. // TODO Check for referenced but missing string files. // Check for bad values in rc.calendar.details. - std::string calendardetails = Context::getContext ().config.get ("calendar.details"); - if (calendardetails != "full" && - calendardetails != "sparse" && - calendardetails != "none") - out << format (STRING_CMD_SHOW_CONFIG_ERROR, "calendar.details", calendardetails) - << '\n'; + std::string calendardetails = Context::getContext().config.get("calendar.details"); + if (calendardetails != "full" && calendardetails != "sparse" && calendardetails != "none") + out << format(STRING_CMD_SHOW_CONFIG_ERROR, "calendar.details", calendardetails) << '\n'; // Check for bad values in rc.calendar.holidays. - std::string calendarholidays = Context::getContext ().config.get ("calendar.holidays"); - if (calendarholidays != "full" && - calendarholidays != "sparse" && - calendarholidays != "none") - out << format (STRING_CMD_SHOW_CONFIG_ERROR, "calendar.holidays", calendarholidays) - << '\n'; + std::string calendarholidays = Context::getContext().config.get("calendar.holidays"); + if (calendarholidays != "full" && calendarholidays != "sparse" && calendarholidays != "none") + out << format(STRING_CMD_SHOW_CONFIG_ERROR, "calendar.holidays", calendarholidays) << '\n'; // Verify installation. This is mentioned in the documentation as the way // to ensure everything is properly installed. - if (Context::getContext ().config.size () == 0) - { + if (Context::getContext().config.size() == 0) { out << "Configuration error: .taskrc contains no entries.\n"; rc = 1; - } - else - { - Directory location (Context::getContext ().config.get ("data.location")); + } else { + Directory location(Context::getContext().config.get("data.location")); if (location._data == "") out << "Configuration error: data.location not specified in .taskrc file.\n"; - if (! location.exists ()) - out << "Configuration error: data.location contains a directory name that doesn't exist, or is unreadable.\n"; + if (!location.exists()) + out << "Configuration error: data.location contains a directory name that doesn't exist, or " + "is unreadable.\n"; } - output = out.str (); + output = out.str(); return rc; } //////////////////////////////////////////////////////////////////////////////// -CmdShowRaw::CmdShowRaw () -{ - _keyword = "_show"; - _usage = "task _show"; +CmdShowRaw::CmdShowRaw() { + _keyword = "_show"; + _usage = "task _show"; _description = "Shows all configuration settings in a machine-readable format"; - _read_only = true; + _read_only = true; _displays_id = false; - _category = Command::Category::internal; + _category = Command::Category::internal; } //////////////////////////////////////////////////////////////////////////////// -int CmdShowRaw::execute (std::string& output) -{ +int CmdShowRaw::execute(std::string& output) { // Get all the settings and sort alphabetically by name. - auto all = Context::getContext ().config.all (); - std::sort (all.begin (), all.end ()); + auto all = Context::getContext().config.all(); + std::sort(all.begin(), all.end()); // Display them all. std::stringstream out; - for (auto& i : all) - out << i << '=' << Context::getContext ().config.get (i) << '\n'; + for (auto& i : all) out << i << '=' << Context::getContext().config.get(i) << '\n'; - output = out.str (); + output = out.str(); return 0; } diff --git a/src/commands/CmdShow.h b/src/commands/CmdShow.h index 2bee52518..cc3f064fd 100644 --- a/src/commands/CmdShow.h +++ b/src/commands/CmdShow.h @@ -27,21 +27,20 @@ #ifndef INCLUDED_CMDSHOW #define INCLUDED_CMDSHOW -#include #include -class CmdShow : public Command -{ -public: - CmdShow (); - int execute (std::string&); +#include + +class CmdShow : public Command { + public: + CmdShow(); + int execute(std::string&); }; -class CmdShowRaw : public Command -{ -public: - CmdShowRaw (); - int execute (std::string&); +class CmdShowRaw : public Command { + public: + CmdShowRaw(); + int execute(std::string&); }; #endif diff --git a/src/commands/CmdStart.cpp b/src/commands/CmdStart.cpp index 1566e1bfb..10a5c9e5c 100644 --- a/src/commands/CmdStart.cpp +++ b/src/commands/CmdStart.cpp @@ -28,115 +28,100 @@ // cmake.h include header must come first #include -#include #include #include -#include #include +#include #include +#include + //////////////////////////////////////////////////////////////////////////////// -CmdStart::CmdStart () -{ - _keyword = "start"; - _usage = "task start "; - _description = "Marks specified task as started"; - _read_only = false; - _displays_id = false; - _needs_gc = false; - _uses_context = true; - _accepts_filter = true; +CmdStart::CmdStart() { + _keyword = "start"; + _usage = "task start "; + _description = "Marks specified task as started"; + _read_only = false; + _displays_id = false; + _needs_gc = false; + _uses_context = true; + _accepts_filter = true; _accepts_modifications = true; _accepts_miscellaneous = false; - _category = Command::Category::operation; + _category = Command::Category::operation; } //////////////////////////////////////////////////////////////////////////////// -int CmdStart::execute (std::string&) -{ +int CmdStart::execute(std::string&) { int rc = 0; int count = 0; // Apply filter. Filter filter; - std::vector filtered; - filter.subset (filtered); - if (filtered.size () == 0) - { - Context::getContext ().footnote ("No tasks specified."); + std::vector filtered; + filter.subset(filtered); + if (filtered.size() == 0) { + Context::getContext().footnote("No tasks specified."); return 1; } // Accumulated project change notifications. - std::map projectChanges; + std::map projectChanges; - if(filtered.size() > 1) { + if (filtered.size() > 1) { feedback_affected("This command will alter {1} tasks.", filtered.size()); } - std::vector modified; - for (auto& task : filtered) - { - if (! task.has ("start")) - { - Task before (task); + std::vector modified; + for (auto& task : filtered) { + if (!task.has("start")) { + Task before(task); // Start the specified task. - std::string question = format ("Start task {1} '{2}'?", - task.identifier (true), - task.get ("description")); - task.setAsNow ("start"); + std::string question = + format("Start task {1} '{2}'?", task.identifier(true), task.get("description")); + task.setAsNow("start"); - Task::status status = task.getStatus (); - if (status == Task::completed || status == Task::deleted) - { + Task::status status = task.getStatus(); + if (status == Task::completed || status == Task::deleted) { // "waiting" handled by Task::validate(), no special care needed here. - task.setStatus (Task::pending); + task.setStatus(Task::pending); } - task.modify (Task::modAnnotate); - if (Context::getContext ().config.getBoolean ("journal.time")) - task.addAnnotation (Context::getContext ().config.get ("journal.time.start.annotation")); + task.modify(Task::modAnnotate); + if (Context::getContext().config.getBoolean("journal.time")) + task.addAnnotation(Context::getContext().config.get("journal.time.start.annotation")); - if (permission (before.diff (task) + question, filtered.size ())) - { - updateRecurrenceMask (task); - Context::getContext ().tdb2.modify (task); + if (permission(before.diff(task) + question, filtered.size())) { + updateRecurrenceMask(task); + Context::getContext().tdb2.modify(task); ++count; - feedback_affected ("Starting task {1} '{2}'.", task); - dependencyChainOnStart (task); - if (Context::getContext ().verbose ("project")) - projectChanges[task.get ("project")] = onProjectChange (task, false); + feedback_affected("Starting task {1} '{2}'.", task); + dependencyChainOnStart(task); + if (Context::getContext().verbose("project")) + projectChanges[task.get("project")] = onProjectChange(task, false); // Save unmodified task for potential nagging later modified.push_back(before); - } - else - { + } else { std::cout << "Task not started.\n"; rc = 1; - if (_permission_quit) - break; + if (_permission_quit) break; } - } - else - { - std::cout << format ("Task {1} '{2}' already started.", - task.id, - task.get ("description")) + } else { + std::cout << format("Task {1} '{2}' already started.", task.id, task.get("description")) << '\n'; rc = 1; } } - nag (modified); + nag(modified); // Now list the project changes. for (auto& change : projectChanges) - if (change.first != "") - Context::getContext ().footnote (change.second); + if (change.first != "") Context::getContext().footnote(change.second); - feedback_affected (count == 1 ? "Started {1} task." : "Started {1} tasks.", count); + feedback_affected(count == 1 ? "Started {1} task." : "Started {1} tasks.", count); return rc; } diff --git a/src/commands/CmdStart.h b/src/commands/CmdStart.h index 81951de17..2c16f46d8 100644 --- a/src/commands/CmdStart.h +++ b/src/commands/CmdStart.h @@ -27,14 +27,14 @@ #ifndef INCLUDED_CMDSTART #define INCLUDED_CMDSTART -#include #include -class CmdStart : public Command -{ -public: - CmdStart (); - int execute (std::string&); +#include + +class CmdStart : public Command { + public: + CmdStart(); + int execute(std::string&); }; #endif diff --git a/src/commands/CmdStats.cpp b/src/commands/CmdStats.cpp index be658bc5f..3450d8f11 100644 --- a/src/commands/CmdStats.cpp +++ b/src/commands/CmdStats.cpp @@ -28,256 +28,248 @@ // cmake.h include header must come first #include -#include -#include -#include -#include +#include #include #include -#include #include -#include +#include #include +#include +#include #include +#include +#include + //////////////////////////////////////////////////////////////////////////////// -CmdStats::CmdStats () -{ - _keyword = "stats"; - _usage = "task stats"; - _description = "Shows task database statistics"; - _read_only = true; - _displays_id = false; - _needs_gc = true; - _uses_context = true; - _accepts_filter = true; +CmdStats::CmdStats() { + _keyword = "stats"; + _usage = "task stats"; + _description = "Shows task database statistics"; + _read_only = true; + _displays_id = false; + _needs_gc = true; + _uses_context = true; + _accepts_filter = true; _accepts_modifications = false; _accepts_miscellaneous = false; - _category = Command::Category::metadata; + _category = Command::Category::metadata; } //////////////////////////////////////////////////////////////////////////////// -int CmdStats::execute (std::string& output) -{ +int CmdStats::execute(std::string& output) { int rc = 0; std::stringstream out; - std::string dateformat = Context::getContext ().config.get ("dateformat"); + std::string dateformat = Context::getContext().config.get("dateformat"); // Count the possible reverts. - int undoCount = Context::getContext ().tdb2.num_reverts_possible (); + int undoCount = Context::getContext().tdb2.num_reverts_possible(); // Count the backlog transactions. - int numLocalChanges = Context::getContext ().tdb2.num_local_changes (); + int numLocalChanges = Context::getContext().tdb2.num_local_changes(); // Get all the tasks. Filter filter; - std::vector all = Context::getContext ().tdb2.all_tasks (); - std::vector filtered; - filter.subset (all, filtered); + std::vector all = Context::getContext().tdb2.all_tasks(); + std::vector filtered; + filter.subset(all, filtered); Datetime now; - time_t earliest = time (nullptr); - time_t latest = 1; - int totalT = 0; - int deletedT = 0; - int pendingT = 0; - int completedT = 0; - int waitingT = 0; - int taggedT = 0; - int annotationsT = 0; - int recurringT = 0; - int blockingT = 0; - int blockedT = 0; + time_t earliest = time(nullptr); + time_t latest = 1; + int totalT = 0; + int deletedT = 0; + int pendingT = 0; + int completedT = 0; + int waitingT = 0; + int taggedT = 0; + int annotationsT = 0; + int recurringT = 0; + int blockingT = 0; + int blockedT = 0; float daysPending = 0.0; - int descLength = 0; - std::map allTags; - std::map allProjects; + int descLength = 0; + std::map allTags; + std::map allProjects; - for (auto& task : filtered) - { + for (auto& task : filtered) { ++totalT; - Task::status status = task.getStatus (); - switch (status) - { - case Task::deleted: ++deletedT; break; - case Task::pending: ++pendingT; break; - case Task::completed: ++completedT; break; - case Task::recurring: ++recurringT; break; - case Task::waiting: ++waitingT; break; + Task::status status = task.getStatus(); + switch (status) { + case Task::deleted: + ++deletedT; + break; + case Task::pending: + ++pendingT; + break; + case Task::completed: + ++completedT; + break; + case Task::recurring: + ++recurringT; + break; + case Task::waiting: + ++waitingT; + break; } - if (task.is_blocked) ++blockedT; + if (task.is_blocked) ++blockedT; if (task.is_blocking) ++blockingT; - time_t entry = strtoll (task.get ("entry").c_str (), nullptr, 10); + time_t entry = strtoll(task.get("entry").c_str(), nullptr, 10); if (entry < earliest) earliest = entry; - if (entry > latest) latest = entry; + if (entry > latest) latest = entry; - if (status == Task::completed) - { - time_t end = strtoll (task.get ("end").c_str (), nullptr, 10); + if (status == Task::completed) { + time_t end = strtoll(task.get("end").c_str(), nullptr, 10); daysPending += (end - entry) / 86400.0; } - if (status == Task::pending) - daysPending += (now.toEpoch () - entry) / 86400.0; + if (status == Task::pending) daysPending += (now.toEpoch() - entry) / 86400.0; - descLength += task.get ("description").length (); - annotationsT += task.getAnnotations ().size (); + descLength += task.get("description").length(); + annotationsT += task.getAnnotations().size(); - auto tags = task.getTags (); - if (tags.size ()) - ++taggedT; + auto tags = task.getTags(); + if (tags.size()) ++taggedT; - for (auto& tag : tags) - allTags[tag] = 0; + for (auto& tag : tags) allTags[tag] = 0; - std::string project = task.get ("project"); - if (project != "") - allProjects[project] = 0; + std::string project = task.get("project"); + if (project != "") allProjects[project] = 0; } // Create a table for output. Table view; - view.width (Context::getContext ().getWidth ()); - view.intraPadding (2); - view.add ("Category"); - view.add ("Data"); - setHeaderUnderline (view); + view.width(Context::getContext().getWidth()); + view.intraPadding(2); + view.add("Category"); + view.add("Data"); + setHeaderUnderline(view); - int row = view.addRow (); - view.set (row, 0, "Pending"); - view.set (row, 1, pendingT); + int row = view.addRow(); + view.set(row, 0, "Pending"); + view.set(row, 1, pendingT); - row = view.addRow (); - view.set (row, 0, "Waiting"); - view.set (row, 1, waitingT); + row = view.addRow(); + view.set(row, 0, "Waiting"); + view.set(row, 1, waitingT); - row = view.addRow (); - view.set (row, 0, "Recurring"); - view.set (row, 1, recurringT); + row = view.addRow(); + view.set(row, 0, "Recurring"); + view.set(row, 1, recurringT); - row = view.addRow (); - view.set (row, 0, "Completed"); - view.set (row, 1, completedT); + row = view.addRow(); + view.set(row, 0, "Completed"); + view.set(row, 1, completedT); - row = view.addRow (); - view.set (row, 0, "Deleted"); - view.set (row, 1, deletedT); + row = view.addRow(); + view.set(row, 0, "Deleted"); + view.set(row, 1, deletedT); - row = view.addRow (); - view.set (row, 0, "Total"); - view.set (row, 1, totalT); + row = view.addRow(); + view.set(row, 0, "Total"); + view.set(row, 1, totalT); - row = view.addRow (); - view.set (row, 0, "Annotations"); - view.set (row, 1, annotationsT); + row = view.addRow(); + view.set(row, 0, "Annotations"); + view.set(row, 1, annotationsT); - row = view.addRow (); - view.set (row, 0, "Unique tags"); - view.set (row, 1, (int)allTags.size ()); + row = view.addRow(); + view.set(row, 0, "Unique tags"); + view.set(row, 1, (int)allTags.size()); - row = view.addRow (); - view.set (row, 0, "Projects"); - view.set (row, 1, (int)allProjects.size ()); + row = view.addRow(); + view.set(row, 0, "Projects"); + view.set(row, 1, (int)allProjects.size()); - row = view.addRow (); - view.set (row, 0, "Blocked tasks"); - view.set (row, 1, blockedT); + row = view.addRow(); + view.set(row, 0, "Blocked tasks"); + view.set(row, 1, blockedT); - row = view.addRow (); - view.set (row, 0, "Blocking tasks"); - view.set (row, 1, blockingT); + row = view.addRow(); + view.set(row, 0, "Blocking tasks"); + view.set(row, 1, blockingT); - row = view.addRow (); - view.set (row, 0, "Undo transactions"); - view.set (row, 1, undoCount); + row = view.addRow(); + view.set(row, 0, "Undo transactions"); + view.set(row, 1, undoCount); - row = view.addRow (); - view.set (row, 0, "Sync backlog transactions"); - view.set (row, 1, numLocalChanges); + row = view.addRow(); + view.set(row, 0, "Sync backlog transactions"); + view.set(row, 1, numLocalChanges); - if (totalT) - { - row = view.addRow (); - view.set (row, 0, "Tasks tagged"); + if (totalT) { + row = view.addRow(); + view.set(row, 0, "Tasks tagged"); std::stringstream value; - value << std::setprecision (3) << (100.0 * taggedT / totalT) << '%'; - view.set (row, 1, value.str ()); + value << std::setprecision(3) << (100.0 * taggedT / totalT) << '%'; + view.set(row, 1, value.str()); } - if (filtered.size ()) - { - Datetime e (earliest); - row = view.addRow (); - view.set (row, 0, "Oldest task"); - view.set (row, 1, e.toString (dateformat)); + if (filtered.size()) { + Datetime e(earliest); + row = view.addRow(); + view.set(row, 0, "Oldest task"); + view.set(row, 1, e.toString(dateformat)); - Datetime l (latest); - row = view.addRow (); - view.set (row, 0, "Newest task"); - view.set (row, 1, l.toString (dateformat)); + Datetime l(latest); + row = view.addRow(); + view.set(row, 0, "Newest task"); + view.set(row, 1, l.toString(dateformat)); - row = view.addRow (); - view.set (row, 0, "Task used for"); - view.set (row, 1, Duration (latest - earliest).formatVague ()); + row = view.addRow(); + view.set(row, 0, "Task used for"); + view.set(row, 1, Duration(latest - earliest).formatVague()); } - if (totalT) - { - row = view.addRow (); - view.set (row, 0, "Task added every"); - view.set (row, 1, Duration (((latest - earliest) / totalT)).formatVague ()); + if (totalT) { + row = view.addRow(); + view.set(row, 0, "Task added every"); + view.set(row, 1, Duration(((latest - earliest) / totalT)).formatVague()); } - if (completedT) - { - row = view.addRow (); - view.set (row, 0, "Task completed every"); - view.set (row, 1, Duration ((latest - earliest) / completedT).formatVague ()); + if (completedT) { + row = view.addRow(); + view.set(row, 0, "Task completed every"); + view.set(row, 1, Duration((latest - earliest) / completedT).formatVague()); } - if (deletedT) - { - row = view.addRow (); - view.set (row, 0, "Task deleted every"); - view.set (row, 1, Duration ((latest - earliest) / deletedT).formatVague ()); + if (deletedT) { + row = view.addRow(); + view.set(row, 0, "Task deleted every"); + view.set(row, 1, Duration((latest - earliest) / deletedT).formatVague()); } - if (pendingT || completedT) - { - row = view.addRow (); - view.set (row, 0, "Average time pending"); - view.set (row, 1, Duration ((int) ((daysPending / (pendingT + completedT)) * 86400)).formatVague ()); + if (pendingT || completedT) { + row = view.addRow(); + view.set(row, 0, "Average time pending"); + view.set(row, 1, + Duration((int)((daysPending / (pendingT + completedT)) * 86400)).formatVague()); } - if (totalT) - { - row = view.addRow (); - view.set (row, 0, "Average desc length"); - view.set (row, 1, format ("{1} characters", (int) (descLength / totalT))); + if (totalT) { + row = view.addRow(); + view.set(row, 0, "Average desc length"); + view.set(row, 1, format("{1} characters", (int)(descLength / totalT))); } // If an alternating row color is specified, notify the table. - if (Context::getContext ().color ()) - { - Color alternate (Context::getContext ().config.get ("color.alternate")); - if (alternate.nontrivial ()) - { - view.colorOdd (alternate); - view.intraColorOdd (alternate); - view.extraColorOdd (alternate); + if (Context::getContext().color()) { + Color alternate(Context::getContext().config.get("color.alternate")); + if (alternate.nontrivial()) { + view.colorOdd(alternate); + view.intraColorOdd(alternate); + view.extraColorOdd(alternate); } } - out << optionalBlankLine () - << view.render () - << optionalBlankLine (); + out << optionalBlankLine() << view.render() << optionalBlankLine(); - output = out.str (); + output = out.str(); return rc; } diff --git a/src/commands/CmdStats.h b/src/commands/CmdStats.h index 2d384c434..b62cbdfd0 100644 --- a/src/commands/CmdStats.h +++ b/src/commands/CmdStats.h @@ -27,14 +27,14 @@ #ifndef INCLUDED_CMDSTATS #define INCLUDED_CMDSTATS -#include #include -class CmdStats : public Command -{ -public: - CmdStats (); - int execute (std::string&); +#include + +class CmdStats : public Command { + public: + CmdStats(); + int execute(std::string&); }; #endif diff --git a/src/commands/CmdStop.cpp b/src/commands/CmdStop.cpp index a46b5840d..2698a8436 100644 --- a/src/commands/CmdStop.cpp +++ b/src/commands/CmdStop.cpp @@ -28,90 +28,78 @@ // cmake.h include header must come first #include -#include #include #include -#include #include +#include + +#include //////////////////////////////////////////////////////////////////////////////// -CmdStop::CmdStop () -{ - _keyword = "stop"; - _usage = "task stop "; - _description = "Removes the 'start' time from a task"; - _read_only = false; - _displays_id = false; - _needs_gc = false; - _uses_context = true; - _accepts_filter = true; +CmdStop::CmdStop() { + _keyword = "stop"; + _usage = "task stop "; + _description = "Removes the 'start' time from a task"; + _read_only = false; + _displays_id = false; + _needs_gc = false; + _uses_context = true; + _accepts_filter = true; _accepts_modifications = true; _accepts_miscellaneous = false; - _category = Command::Category::operation; + _category = Command::Category::operation; } //////////////////////////////////////////////////////////////////////////////// -int CmdStop::execute (std::string&) -{ +int CmdStop::execute(std::string&) { int rc = 0; int count = 0; // Apply filter. Filter filter; - std::vector filtered; - filter.subset (filtered); - if (filtered.size () == 0) - { - Context::getContext ().footnote ("No tasks specified."); + std::vector filtered; + filter.subset(filtered); + if (filtered.size() == 0) { + Context::getContext().footnote("No tasks specified."); return 1; } // Accumulated project change notifications. - std::map projectChanges; + std::map projectChanges; - if(filtered.size() > 1) { + if (filtered.size() > 1) { feedback_affected("This command will alter {1} tasks.", filtered.size()); } - for (auto& task : filtered) - { - if (task.has ("start")) - { - Task before (task); + for (auto& task : filtered) { + if (task.has("start")) { + Task before(task); // Stop the specified task. - std::string question = format ("Stop task {1} '{2}'?", - task.identifier (true), - task.get ("description")); + std::string question = + format("Stop task {1} '{2}'?", task.identifier(true), task.get("description")); - task.modify (Task::modAnnotate); - task.remove ("start"); + task.modify(Task::modAnnotate); + task.remove("start"); - if (Context::getContext ().config.getBoolean ("journal.time")) - task.addAnnotation (Context::getContext ().config.get ("journal.time.stop.annotation")); + if (Context::getContext().config.getBoolean("journal.time")) + task.addAnnotation(Context::getContext().config.get("journal.time.stop.annotation")); - if (permission (before.diff (task) + question, filtered.size ())) - { - updateRecurrenceMask (task); - Context::getContext ().tdb2.modify (task); + if (permission(before.diff(task) + question, filtered.size())) { + updateRecurrenceMask(task); + Context::getContext().tdb2.modify(task); ++count; - feedback_affected ("Stopping task {1} '{2}'.", task); - dependencyChainOnStart (task); - if (Context::getContext ().verbose ("project")) - projectChanges[task.get ("project")] = onProjectChange (task, false); - } - else - { + feedback_affected("Stopping task {1} '{2}'.", task); + dependencyChainOnStart(task); + if (Context::getContext().verbose("project")) + projectChanges[task.get("project")] = onProjectChange(task, false); + } else { std::cout << "Task not stopped.\n"; rc = 1; - if (_permission_quit) - break; + if (_permission_quit) break; } - } - else - { - std::cout << format ("Task {1} '{2}' not started.", - task.identifier (true), - task.get ("description")) + } else { + std::cout << format("Task {1} '{2}' not started.", task.identifier(true), + task.get("description")) << '\n'; rc = 1; } @@ -119,10 +107,9 @@ int CmdStop::execute (std::string&) // Now list the project changes. for (auto& change : projectChanges) - if (change.first != "") - Context::getContext ().footnote (change.second); + if (change.first != "") Context::getContext().footnote(change.second); - feedback_affected (count == 1 ? "Stopped {1} task." : "Stopped {1} tasks.", count); + feedback_affected(count == 1 ? "Stopped {1} task." : "Stopped {1} tasks.", count); return rc; } diff --git a/src/commands/CmdStop.h b/src/commands/CmdStop.h index fb28a444c..695a4c25c 100644 --- a/src/commands/CmdStop.h +++ b/src/commands/CmdStop.h @@ -27,14 +27,14 @@ #ifndef INCLUDED_CMDSTOP #define INCLUDED_CMDSTOP -#include #include -class CmdStop : public Command -{ -public: - CmdStop (); - int execute (std::string&); +#include + +class CmdStop : public Command { + public: + CmdStop(); + int execute(std::string&); }; #endif diff --git a/src/commands/CmdSummary.cpp b/src/commands/CmdSummary.cpp index 5564a8829..76a83a29b 100644 --- a/src/commands/CmdSummary.cpp +++ b/src/commands/CmdSummary.cpp @@ -28,186 +28,160 @@ // cmake.h include header must come first #include -#include -#include -#include #include +#include #include #include -#include #include -#include #include +#include +#include + +#include #include +#include //////////////////////////////////////////////////////////////////////////////// -CmdSummary::CmdSummary () -{ - _keyword = "summary"; - _usage = "task summary"; - _description = "Shows a report of task status by project"; - _read_only = true; - _displays_id = false; - _needs_gc = true; - _uses_context = true; - _accepts_filter = true; +CmdSummary::CmdSummary() { + _keyword = "summary"; + _usage = "task summary"; + _description = "Shows a report of task status by project"; + _read_only = true; + _displays_id = false; + _needs_gc = true; + _uses_context = true; + _accepts_filter = true; _accepts_modifications = false; _accepts_miscellaneous = false; - _category = Command::Category::graphs; + _category = Command::Category::graphs; } //////////////////////////////////////////////////////////////////////////////// // Project Remaining Avg Age Complete 0% 100% // A 12 13d 55% XXXXXXXXXXXXX----------- // B 109 3d 12h 10% XXX--------------------- -int CmdSummary::execute (std::string& output) -{ +int CmdSummary::execute(std::string& output) { int rc = 0; - bool showAllProjects = Context::getContext ().config.getBoolean ("summary.all.projects"); + bool showAllProjects = Context::getContext().config.getBoolean("summary.all.projects"); // Apply filter. - handleUntil (); - handleRecurrence (); + handleUntil(); + handleRecurrence(); Filter filter; - std::vector filtered; - filter.subset (filtered); + std::vector filtered; + filter.subset(filtered); // Generate unique list of project names from all pending tasks. - std::map allProjects; + std::map allProjects; for (auto& task : filtered) - if (showAllProjects || task.getStatus () == Task::pending) - allProjects[task.get ("project")] = false; + if (showAllProjects || task.getStatus() == Task::pending) + allProjects[task.get("project")] = false; // Initialize counts, sum. - std::map countPending; - std::map countCompleted; - std::map sumEntry; - std::map counter; - time_t now = time (nullptr); + std::map countPending; + std::map countCompleted; + std::map sumEntry; + std::map counter; + time_t now = time(nullptr); // Initialize counters. - for (auto& project : allProjects) - { - countPending [project.first] = 0; - countCompleted [project.first] = 0; - sumEntry [project.first] = 0.0; - counter [project.first] = 0; + for (auto& project : allProjects) { + countPending[project.first] = 0; + countCompleted[project.first] = 0; + sumEntry[project.first] = 0.0; + counter[project.first] = 0; } // Count the various tasks. - for (auto& task : filtered) - { - std::string project = task.get ("project"); - std::vector projects = extractParents (project); - projects.push_back (project); + for (auto& task : filtered) { + std::string project = task.get("project"); + std::vector projects = extractParents(project); + projects.push_back(project); - for (auto& parent : projects) - ++counter[parent]; + for (auto& parent : projects) ++counter[parent]; - if (task.getStatus () == Task::pending || - task.getStatus () == Task::waiting) - { - for (auto& parent : projects) - { + if (task.getStatus() == Task::pending || task.getStatus() == Task::waiting) { + for (auto& parent : projects) { ++countPending[parent]; - time_t entry = strtoll (task.get ("entry").c_str (), nullptr, 10); - if (entry) - sumEntry[parent] = sumEntry[parent] + (double) (now - entry); + time_t entry = strtoll(task.get("entry").c_str(), nullptr, 10); + if (entry) sumEntry[parent] = sumEntry[parent] + (double)(now - entry); } } - else if (task.getStatus () == Task::completed) - { - for (auto& parent : projects) - { + else if (task.getStatus() == Task::completed) { + for (auto& parent : projects) { ++countCompleted[parent]; - time_t entry = strtoll (task.get ("entry").c_str (), nullptr, 10); - time_t end = strtoll (task.get ("end").c_str (), nullptr, 10); - if (entry && end) - sumEntry[parent] = sumEntry[parent] + (double) (end - entry); + time_t entry = strtoll(task.get("entry").c_str(), nullptr, 10); + time_t end = strtoll(task.get("end").c_str(), nullptr, 10); + if (entry && end) sumEntry[parent] = sumEntry[parent] + (double)(end - entry); } } } // Create a table for output. Table view; - view.width (Context::getContext ().getWidth ()); - view.add ("Project"); - view.add ("Remaining", false); - view.add ("Avg age", false); - view.add ("Complete", false); - view.add ("0% 100%", true, false); - setHeaderUnderline (view); + view.width(Context::getContext().getWidth()); + view.add("Project"); + view.add("Remaining", false); + view.add("Avg age", false); + view.add("Complete", false); + view.add("0% 100%", true, false); + setHeaderUnderline(view); Color bar_color; Color bg_color; - if (Context::getContext ().color ()) - { - bar_color = Color (Context::getContext ().config.get ("color.summary.bar")); - bg_color = Color (Context::getContext ().config.get ("color.summary.background")); + if (Context::getContext().color()) { + bar_color = Color(Context::getContext().config.get("color.summary.bar")); + bg_color = Color(Context::getContext().config.get("color.summary.background")); } // sort projects into sorted list std::list> sortedProjects; - sort_projects (sortedProjects, allProjects); + sort_projects(sortedProjects, allProjects); int barWidth = 30; // construct view from sorted list - for (auto& i : sortedProjects) - { - int row = view.addRow (); - view.set (row, 0, (i.first == "" - ? "(none)" - : indentProject (i.first, " ", '.'))); + for (auto& i : sortedProjects) { + int row = view.addRow(); + view.set(row, 0, (i.first == "" ? "(none)" : indentProject(i.first, " ", '.'))); - view.set (row, 1, countPending[i.first]); - if (counter[i.first]) - view.set (row, 2, Duration ((int) (sumEntry[i.first] / (double)counter[i.first])).formatVague ()); + view.set(row, 1, countPending[i.first]); + if (counter[i.first]) + view.set(row, 2, Duration((int)(sumEntry[i.first] / (double)counter[i.first])).formatVague()); - int c = countCompleted[i.first]; - int p = countPending[i.first]; - int completedBar = 0; - if (c + p) - completedBar = (c * barWidth) / (c + p); + int c = countCompleted[i.first]; + int p = countPending[i.first]; + int completedBar = 0; + if (c + p) completedBar = (c * barWidth) / (c + p); - std::string bar; - std::string subbar; - if (Context::getContext ().color ()) - { - bar += bar_color.colorize (std::string ( completedBar, ' ')); - bar += bg_color.colorize (std::string (barWidth - completedBar, ' ')); - } - else - { - bar += std::string ( completedBar, '=') - + std::string (barWidth - completedBar, ' '); - } - view.set (row, 4, bar); + std::string bar; + std::string subbar; + if (Context::getContext().color()) { + bar += bar_color.colorize(std::string(completedBar, ' ')); + bar += bg_color.colorize(std::string(barWidth - completedBar, ' ')); + } else { + bar += std::string(completedBar, '=') + std::string(barWidth - completedBar, ' '); + } + view.set(row, 4, bar); - char percent[12] = "0%"; - if (c + p) - snprintf (percent, 12, "%d%%", 100 * c / (c + p)); - view.set (row, 3, percent); + char percent[12] = "0%"; + if (c + p) snprintf(percent, 12, "%d%%", 100 * c / (c + p)); + view.set(row, 3, percent); } std::stringstream out; - if (view.rows ()) - { - out << optionalBlankLine () - << view.render () - << optionalBlankLine (); + if (view.rows()) { + out << optionalBlankLine() << view.render() << optionalBlankLine(); - out << format ("{1} projects\n", view.rows ()); - } - else - { + out << format("{1} projects\n", view.rows()); + } else { out << "No projects.\n"; rc = 1; } - output = out.str (); + output = out.str(); return rc; } diff --git a/src/commands/CmdSummary.h b/src/commands/CmdSummary.h index 012a062b9..abfe521a5 100644 --- a/src/commands/CmdSummary.h +++ b/src/commands/CmdSummary.h @@ -27,14 +27,14 @@ #ifndef INCLUDED_CMDSUMMARY #define INCLUDED_CMDSUMMARY -#include #include -class CmdSummary : public Command -{ -public: - CmdSummary (); - int execute (std::string&); +#include + +class CmdSummary : public Command { + public: + CmdSummary(); + int execute(std::string&); }; #endif diff --git a/src/commands/CmdSync.cpp b/src/commands/CmdSync.cpp index 3a6dc8144..6245b5acc 100644 --- a/src/commands/CmdSync.cpp +++ b/src/commands/CmdSync.cpp @@ -28,74 +28,74 @@ // cmake.h include header must come first #include -#include -#include -#include +#include #include #include -#include -#include #include +#include +#include +#include #include + +#include + #include "tc/Server.h" //////////////////////////////////////////////////////////////////////////////// -CmdSync::CmdSync () -{ - _keyword = "synchronize"; - _usage = "task synchronize [initialize]"; - _description = "Synchronizes data with the Taskserver"; - _read_only = false; - _displays_id = false; - _needs_gc = false; - _uses_context = false; - _accepts_filter = false; +CmdSync::CmdSync() { + _keyword = "synchronize"; + _usage = "task synchronize [initialize]"; + _description = "Synchronizes data with the Taskserver"; + _read_only = false; + _displays_id = false; + _needs_gc = false; + _uses_context = false; + _accepts_filter = false; _accepts_modifications = false; _accepts_miscellaneous = true; - _category = Command::Category::migration; + _category = Command::Category::migration; } //////////////////////////////////////////////////////////////////////////////// -int CmdSync::execute (std::string& output) -{ +int CmdSync::execute(std::string& output) { int status = 0; tc::Server server; std::string server_ident; // If no server is set up, quit. - std::string origin = Context::getContext ().config.get ("sync.server.origin"); - std::string url = Context::getContext ().config.get ("sync.server.url"); - std::string server_dir = Context::getContext ().config.get ("sync.local.server_dir"); - std::string gcp_credential_path = Context::getContext ().config.get ("sync.gcp.credential_path"); - std::string gcp_bucket = Context::getContext ().config.get ("sync.gcp.bucket"); - std::string encryption_secret = Context::getContext ().config.get ("sync.encryption_secret"); + std::string origin = Context::getContext().config.get("sync.server.origin"); + std::string url = Context::getContext().config.get("sync.server.url"); + std::string server_dir = Context::getContext().config.get("sync.local.server_dir"); + std::string gcp_credential_path = Context::getContext().config.get("sync.gcp.credential_path"); + std::string gcp_bucket = Context::getContext().config.get("sync.gcp.bucket"); + std::string encryption_secret = Context::getContext().config.get("sync.encryption_secret"); // sync.server.origin is a deprecated synonym for sync.server.url std::string server_url = url == "" ? origin : url; if (server_dir != "") { - server = tc::Server::new_local (server_dir); + server = tc::Server::new_local(server_dir); server_ident = server_dir; } else if (gcp_bucket != "") { if (encryption_secret == "") { - throw std::string ("sync.encryption_secret is required"); + throw std::string("sync.encryption_secret is required"); } - server = tc::Server::new_gcp (gcp_bucket, gcp_credential_path, encryption_secret); + server = tc::Server::new_gcp(gcp_bucket, gcp_credential_path, encryption_secret); std::ostringstream os; os << "GCP bucket " << gcp_bucket; server_ident = os.str(); } else if (server_url != "") { - std::string client_id = Context::getContext ().config.get ("sync.server.client_id"); + std::string client_id = Context::getContext().config.get("sync.server.client_id"); if (client_id == "" || encryption_secret == "") { - throw std::string ("sync.server.client_id and sync.encryption_secret are required"); + throw std::string("sync.server.client_id and sync.encryption_secret are required"); } - server = tc::Server::new_sync (server_url, client_id, encryption_secret); + server = tc::Server::new_sync(server_url, client_id, encryption_secret); std::ostringstream os; os << "Sync server at " << server_url; server_ident = os.str(); } else { - throw std::string ("No sync.* settings are configured. See task-sync(5)."); + throw std::string("No sync.* settings are configured. See task-sync(5)."); } std::stringstream out; @@ -103,19 +103,18 @@ int CmdSync::execute (std::string& output) out << "sync.server.origin is deprecated. Use sync.server.url instead.\n"; } - if (Context::getContext ().verbose ("sync")) { - out << format ("Syncing with {1}", server_ident) - << '\n'; + if (Context::getContext().verbose("sync")) { + out << format("Syncing with {1}", server_ident) << '\n'; } - Context &context = Context::getContext (); + Context& context = Context::getContext(); context.tdb2.sync(std::move(server), false); - if (context.config.getBoolean ("purge.on-sync")) { - context.tdb2.expire_tasks (); + if (context.config.getBoolean("purge.on-sync")) { + context.tdb2.expire_tasks(); } - output = out.str (); + output = out.str(); return status; } diff --git a/src/commands/CmdSync.h b/src/commands/CmdSync.h index b823a04f9..8f0bbbba4 100644 --- a/src/commands/CmdSync.h +++ b/src/commands/CmdSync.h @@ -27,15 +27,15 @@ #ifndef INCLUDED_CMDSYNC #define INCLUDED_CMDSYNC -#include #include #include -class CmdSync : public Command -{ -public: - CmdSync (); - int execute (std::string&); +#include + +class CmdSync : public Command { + public: + CmdSync(); + int execute(std::string&); }; #endif diff --git a/src/commands/CmdTags.cpp b/src/commands/CmdTags.cpp index 9d43d4040..a0317d4fb 100644 --- a/src/commands/CmdTags.cpp +++ b/src/commands/CmdTags.cpp @@ -28,200 +28,184 @@ // cmake.h include header must come first #include -#include -#include -#include #include #include #include #include +#include #include +#include +#include + //////////////////////////////////////////////////////////////////////////////// -CmdTags::CmdTags () -{ - _keyword = "tags"; - _usage = "task tags"; - _description = "Shows a list of all tags used"; - _read_only = true; - _displays_id = false; - _needs_gc = true; - _uses_context = true; - _accepts_filter = true; +CmdTags::CmdTags() { + _keyword = "tags"; + _usage = "task tags"; + _description = "Shows a list of all tags used"; + _read_only = true; + _displays_id = false; + _needs_gc = true; + _uses_context = true; + _accepts_filter = true; _accepts_modifications = false; _accepts_miscellaneous = false; - _category = Command::Category::metadata; + _category = Command::Category::metadata; } //////////////////////////////////////////////////////////////////////////////// -int CmdTags::execute (std::string& output) -{ +int CmdTags::execute(std::string& output) { int rc = 0; std::stringstream out; // Get all the tasks. - auto tasks = Context::getContext ().tdb2.pending_tasks (); + auto tasks = Context::getContext().tdb2.pending_tasks(); - if (Context::getContext ().config.getBoolean ("list.all.tags")) - for (auto& task : Context::getContext ().tdb2.completed_tasks ()) - tasks.push_back (task); + if (Context::getContext().config.getBoolean("list.all.tags")) + for (auto& task : Context::getContext().tdb2.completed_tasks()) tasks.push_back(task); - int quantity = tasks.size (); + int quantity = tasks.size(); // Apply filter. Filter filter; - std::vector filtered; - filter.subset (tasks, filtered); + std::vector filtered; + filter.subset(tasks, filtered); // Scan all the tasks for their project name, building a map using project // names as keys. - std::map unique; - for (auto& task : filtered) - { - for (auto& tag : task.getTags ()) - if (unique.find (tag) != unique.end ()) + std::map unique; + for (auto& task : filtered) { + for (auto& tag : task.getTags()) + if (unique.find(tag) != unique.end()) unique[tag]++; else unique[tag] = 1; } - if (unique.size ()) - { + if (unique.size()) { // Render a list of tags names from the map. Table view; - view.width (Context::getContext ().getWidth ()); - view.add ("Tag"); - view.add ("Count", false); - setHeaderUnderline (view); + view.width(Context::getContext().getWidth()); + view.add("Tag"); + view.add("Count", false); + setHeaderUnderline(view); Color bold; - if (Context::getContext ().color ()) - bold = Color ("bold"); + if (Context::getContext().color()) bold = Color("bold"); bool special = false; - for (auto& i : unique) - { + for (auto& i : unique) { // Highlight the special tags. - special = (Context::getContext ().color () && - (i.first == "nocolor" || - i.first == "nonag" || - i.first == "nocal" || - i.first == "next")) ? true : false; + special = (Context::getContext().color() && (i.first == "nocolor" || i.first == "nonag" || + i.first == "nocal" || 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 ()); + 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 (); + out << optionalBlankLine() << view.render() << optionalBlankLine(); - if (unique.size () == 1) - Context::getContext ().footnote ("1 tag"); + if (unique.size() == 1) + Context::getContext().footnote("1 tag"); else - Context::getContext ().footnote (format ("{1} tags", unique.size ())); + Context::getContext().footnote(format("{1} tags", unique.size())); if (quantity == 1) - Context::getContext ().footnote ("(1 task)"); + Context::getContext().footnote("(1 task)"); else - Context::getContext ().footnote (format ("({1} tasks)", quantity)); + Context::getContext().footnote(format("({1} tasks)", quantity)); out << '\n'; - } - else - { - Context::getContext ().footnote ("No tags."); + } else { + Context::getContext().footnote("No tags."); rc = 1; } - output = out.str (); + output = out.str(); return rc; } //////////////////////////////////////////////////////////////////////////////// -CmdCompletionTags::CmdCompletionTags () -{ - _keyword = "_tags"; - _usage = "task _tags"; - _description = "Shows only a list of all tags used, for autocompletion purposes"; - _read_only = true; - _displays_id = false; - _needs_gc = true; - _uses_context = false; - _accepts_filter = true; +CmdCompletionTags::CmdCompletionTags() { + _keyword = "_tags"; + _usage = "task _tags"; + _description = "Shows only a list of all tags used, for autocompletion purposes"; + _read_only = true; + _displays_id = false; + _needs_gc = true; + _uses_context = false; + _accepts_filter = true; _accepts_modifications = false; _accepts_miscellaneous = false; - _category = Command::Category::internal; + _category = Command::Category::internal; } //////////////////////////////////////////////////////////////////////////////// -int CmdCompletionTags::execute (std::string& output) -{ +int CmdCompletionTags::execute(std::string& output) { // Get all the tasks. - auto tasks = Context::getContext ().tdb2.pending_tasks (); + auto tasks = Context::getContext().tdb2.pending_tasks(); - if (Context::getContext ().config.getBoolean ("complete.all.tags")) - for (auto& task : Context::getContext ().tdb2.completed_tasks ()) - tasks.push_back (task); + if (Context::getContext().config.getBoolean("complete.all.tags")) + for (auto& task : Context::getContext().tdb2.completed_tasks()) tasks.push_back(task); // Apply filter. Filter filter; - std::vector filtered; - filter.subset (tasks, filtered); + std::vector filtered; + filter.subset(tasks, filtered); // Scan all the tasks for their tags, building a map using tag // names as keys. - std::map unique; + std::map unique; for (auto& task : filtered) - for (auto& tag : task.getTags ()) - unique[tag] = 0; + for (auto& tag : task.getTags()) unique[tag] = 0; // Add built-in tags to map. - unique["nocolor"] = 0; - unique["nonag"] = 0; - unique["nocal"] = 0; - unique["next"] = 0; - unique["ACTIVE"] = 0; + unique["nocolor"] = 0; + unique["nonag"] = 0; + unique["nocal"] = 0; + unique["next"] = 0; + unique["ACTIVE"] = 0; unique["ANNOTATED"] = 0; - unique["BLOCKED"] = 0; - unique["BLOCKING"] = 0; - unique["CHILD"] = 0; // 2017-01-07: Deprecated in 2.6.0 + unique["BLOCKED"] = 0; + unique["BLOCKING"] = 0; + unique["CHILD"] = 0; // 2017-01-07: Deprecated in 2.6.0 unique["COMPLETED"] = 0; - unique["DELETED"] = 0; - unique["DUE"] = 0; - unique["DUETODAY"] = 0; // 2016-03-29: Deprecated in 2.6.0 - unique["INSTANCE"] = 0; - unique["LATEST"] = 0; - unique["MONTH"] = 0; - unique["ORPHAN"] = 0; - unique["OVERDUE"] = 0; - unique["PARENT"] = 0; // 2017-01-07: Deprecated in 2.6.0 - unique["PENDING"] = 0; - unique["PRIORITY"] = 0; - unique["PROJECT"] = 0; - unique["QUARTER"] = 0; - unique["READY"] = 0; + unique["DELETED"] = 0; + unique["DUE"] = 0; + unique["DUETODAY"] = 0; // 2016-03-29: Deprecated in 2.6.0 + unique["INSTANCE"] = 0; + unique["LATEST"] = 0; + unique["MONTH"] = 0; + unique["ORPHAN"] = 0; + unique["OVERDUE"] = 0; + unique["PARENT"] = 0; // 2017-01-07: Deprecated in 2.6.0 + unique["PENDING"] = 0; + unique["PRIORITY"] = 0; + unique["PROJECT"] = 0; + unique["QUARTER"] = 0; + unique["READY"] = 0; unique["SCHEDULED"] = 0; - unique["TAGGED"] = 0; - unique["TEMPLATE"] = 0; - unique["TODAY"] = 0; - unique["TOMORROW"] = 0; - unique["UDA"] = 0; + unique["TAGGED"] = 0; + unique["TEMPLATE"] = 0; + unique["TODAY"] = 0; + unique["TOMORROW"] = 0; + unique["UDA"] = 0; unique["UNBLOCKED"] = 0; - unique["UNTIL"] = 0; - unique["WAITING"] = 0; - unique["WEEK"] = 0; - unique["YEAR"] = 0; + unique["UNTIL"] = 0; + unique["WAITING"] = 0; + unique["WEEK"] = 0; + unique["YEAR"] = 0; unique["YESTERDAY"] = 0; // If you update the above list, update src/commands/CmdInfo.cpp and src/Task.cpp as well. std::stringstream out; - for (auto& it : unique) - out << it.first << '\n'; + for (auto& it : unique) out << it.first << '\n'; - output = out.str (); + output = out.str(); return 0; } diff --git a/src/commands/CmdTags.h b/src/commands/CmdTags.h index 0e54e7a00..84d2345b6 100644 --- a/src/commands/CmdTags.h +++ b/src/commands/CmdTags.h @@ -27,21 +27,20 @@ #ifndef INCLUDED_CMDTAGS #define INCLUDED_CMDTAGS -#include #include -class CmdTags : public Command -{ -public: - CmdTags (); - int execute (std::string&); +#include + +class CmdTags : public Command { + public: + CmdTags(); + int execute(std::string&); }; -class CmdCompletionTags : public Command -{ -public: - CmdCompletionTags (); - int execute (std::string&); +class CmdCompletionTags : public Command { + public: + CmdCompletionTags(); + int execute(std::string&); }; #endif diff --git a/src/commands/CmdTimesheet.cpp b/src/commands/CmdTimesheet.cpp index 63eddf328..bd076acd3 100644 --- a/src/commands/CmdTimesheet.cpp +++ b/src/commands/CmdTimesheet.cpp @@ -28,190 +28,170 @@ // cmake.h include header must come first #include -#include -#include -#include #include +#include #include #include -#include -#include -#include #include +#include +#include +#include + +#include +#include //////////////////////////////////////////////////////////////////////////////// -CmdTimesheet::CmdTimesheet () -{ - _keyword = "timesheet"; - _usage = "task [filter] timesheet"; - _description = "Summary of completed and started tasks"; - _read_only = true; - _displays_id = false; - _needs_gc = true; - _uses_context = false; - _accepts_filter = true; +CmdTimesheet::CmdTimesheet() { + _keyword = "timesheet"; + _usage = "task [filter] timesheet"; + _description = "Summary of completed and started tasks"; + _read_only = true; + _displays_id = false; + _needs_gc = true; + _uses_context = false; + _accepts_filter = true; _accepts_modifications = false; _accepts_miscellaneous = false; - _category = Command::Category::report; + _category = Command::Category::report; } //////////////////////////////////////////////////////////////////////////////// // Whether a the timesheet uses context is defined by the // report.timesheet.context configuration variable. // -bool CmdTimesheet::uses_context () const -{ - auto config = Context::getContext ().config; +bool CmdTimesheet::uses_context() const { + auto config = Context::getContext().config; auto key = "report.timesheet.context"; - if (config.has (key)) - return config.getBoolean (key); + if (config.has(key)) + return config.getBoolean(key); else return _uses_context; } - //////////////////////////////////////////////////////////////////////////////// -int CmdTimesheet::execute (std::string& output) -{ +int CmdTimesheet::execute(std::string& output) { int rc = 0; // Detect a filter. - bool hasFilter {false}; - for (auto& a : Context::getContext ().cli2._args) - { - if (a.hasTag ("FILTER")) - { + bool hasFilter{false}; + for (auto& a : Context::getContext().cli2._args) { + if (a.hasTag("FILTER")) { hasFilter = true; break; } } - if (! hasFilter) - { - auto defaultFilter = Context::getContext ().config.get ("report.timesheet.filter"); + if (!hasFilter) { + auto defaultFilter = Context::getContext().config.get("report.timesheet.filter"); if (defaultFilter == "") defaultFilter = "(+PENDING and start.after:now-4wks) or (+COMPLETED and end.after:now-4wks)"; - Context::getContext ().cli2.addFilter (defaultFilter); + Context::getContext().cli2.addFilter(defaultFilter); } // Apply filter to get a set of tasks. - handleUntil (); - handleRecurrence (); + handleUntil(); + handleRecurrence(); Filter filter; - std::vector filtered; - filter.subset (filtered); + std::vector filtered; + filter.subset(filtered); // Subset the tasks to only those that are either completed or started. // The _key attribute is represents either the 'start' or 'end' date. int num_completed = 0; int num_started = 0; - std::vector shown; - for (auto& task : filtered) - { - if (task.getStatus () == Task::completed) - { - task.set ("_key", task.get ("end")); + std::vector shown; + for (auto& task : filtered) { + if (task.getStatus() == Task::completed) { + task.set("_key", task.get("end")); ++num_completed; } - if (task.getStatus () == Task::pending && task.has ("start")) - { - task.set ("_key", task.get ("start")); + if (task.getStatus() == Task::pending && task.has("start")) { + task.set("_key", task.get("start")); ++num_started; } - shown.push_back (task); + shown.push_back(task); } // Sort tasks by _key. - std::sort (shown.begin (), - shown.end (), - [](const Task& a, const Task& b) { return a.get ("_key") < b.get ("_key"); }); + std::sort(shown.begin(), shown.end(), + [](const Task& a, const Task& b) { return a.get("_key") < b.get("_key"); }); // Render the completed table. Table table; - table.width (Context::getContext ().getWidth ()); - if (Context::getContext ().config.getBoolean ("obfuscate")) - table.obfuscate (); - table.add ("Wk"); - table.add ("Date"); - table.add ("Day"); - table.add ("ID"); - table.add ("Action"); - table.add ("Project"); - table.add ("Due"); - table.add ("Task"); - setHeaderUnderline (table); + table.width(Context::getContext().getWidth()); + if (Context::getContext().config.getBoolean("obfuscate")) table.obfuscate(); + table.add("Wk"); + table.add("Date"); + table.add("Day"); + table.add("ID"); + table.add("Action"); + table.add("Project"); + table.add("Due"); + table.add("Task"); + setHeaderUnderline(table); - auto dateformat = Context::getContext ().config.get ("dateformat"); + auto dateformat = Context::getContext().config.get("dateformat"); int previous_week = -1; std::string previous_date = ""; std::string previous_day = ""; int weekCounter = 0; Color week_color; - for (auto& task : shown) - { - Datetime key (task.get_date ("_key")); + for (auto& task : shown) { + Datetime key(task.get_date("_key")); - std::string label = task.has ("end") ? "Completed" - : task.has ("start") ? "Started" - : ""; + std::string label = task.has("end") ? "Completed" : task.has("start") ? "Started" : ""; - auto week = key.week (); - auto date = key.toString (dateformat); - auto due = task.has ("due") ? Datetime (task.get ("due")).toString (dateformat) : ""; - auto day = Datetime::dayNameShort (key.dayOfWeek ()); + auto week = key.week(); + auto date = key.toString(dateformat); + auto due = task.has("due") ? Datetime(task.get("due")).toString(dateformat) : ""; + auto day = Datetime::dayNameShort(key.dayOfWeek()); Color task_color; - autoColorize (task, task_color); + autoColorize(task, task_color); // Add a blank line between weeks. - if (week != previous_week && previous_week != -1) - { - auto row = table.addRowEven (); - table.set (row, 0, " "); + if (week != previous_week && previous_week != -1) { + auto row = table.addRowEven(); + table.set(row, 0, " "); } // Keep track of unique week numbers. - if (week != previous_week) - ++weekCounter; + if (week != previous_week) ++weekCounter; // User-defined oddness. int row; if (weekCounter % 2) - row = table.addRowOdd (); + row = table.addRowOdd(); else - row = table.addRowEven (); + row = table.addRowEven(); // If the data doesn't change, it doesn't get shown. - table.set (row, 0, (week != previous_week ? format ("W{1}", week) : "")); - table.set (row, 1, (date != previous_date ? date : "")); - table.set (row, 2, (day != previous_day ? day : "")); - table.set (row, 3, task.identifier(true)); - table.set (row, 4, label); - table.set (row, 5, task.get ("project")); - table.set (row, 6, due); - table.set (row, 7, task.get ("description"), task_color); + table.set(row, 0, (week != previous_week ? format("W{1}", week) : "")); + table.set(row, 1, (date != previous_date ? date : "")); + table.set(row, 2, (day != previous_day ? day : "")); + table.set(row, 3, task.identifier(true)); + table.set(row, 4, label); + table.set(row, 5, task.get("project")); + table.set(row, 6, due); + table.set(row, 7, task.get("description"), task_color); previous_week = week; previous_date = date; - previous_day = day; + previous_day = day; } // Render the table. std::stringstream out; - if (table.rows ()) - out << optionalBlankLine () - << table.render () - << '\n'; + if (table.rows()) out << optionalBlankLine() << table.render() << '\n'; - if (Context::getContext ().verbose ("affected")) - out << format ("{1} completed, {2} started.", num_completed, num_started) - << '\n'; + if (Context::getContext().verbose("affected")) + out << format("{1} completed, {2} started.", num_completed, num_started) << '\n'; - output = out.str (); + output = out.str(); return rc; } diff --git a/src/commands/CmdTimesheet.h b/src/commands/CmdTimesheet.h index 3401abec6..4a5c96979 100644 --- a/src/commands/CmdTimesheet.h +++ b/src/commands/CmdTimesheet.h @@ -27,15 +27,15 @@ #ifndef INCLUDED_CMDTIMESHEET #define INCLUDED_CMDTIMESHEET -#include #include -class CmdTimesheet : public Command -{ -public: - CmdTimesheet (); - int execute (std::string&) override; - bool uses_context () const override; +#include + +class CmdTimesheet : public Command { + public: + CmdTimesheet(); + int execute(std::string&) override; + bool uses_context() const override; }; #endif diff --git a/src/commands/CmdUDAs.cpp b/src/commands/CmdUDAs.cpp index 55fa33e6f..540d1726b 100644 --- a/src/commands/CmdUDAs.cpp +++ b/src/commands/CmdUDAs.cpp @@ -28,182 +28,154 @@ // cmake.h include header must come first #include -#include -#include -#include #include #include -#include +#include +#include #include +#include #include #include -#include + +#include +#include //////////////////////////////////////////////////////////////////////////////// -CmdUDAs::CmdUDAs () -{ - _keyword = "udas"; - _usage = "task udas"; - _description = "Shows all the defined UDA details"; - _read_only = true; - _displays_id = false; - _needs_gc = false; - _uses_context = false; - _accepts_filter = false; +CmdUDAs::CmdUDAs() { + _keyword = "udas"; + _usage = "task udas"; + _description = "Shows all the defined UDA details"; + _read_only = true; + _displays_id = false; + _needs_gc = false; + _uses_context = false; + _accepts_filter = false; _accepts_modifications = false; _accepts_miscellaneous = false; - _category = Command::Category::config; + _category = Command::Category::config; } //////////////////////////////////////////////////////////////////////////////// -int CmdUDAs::execute (std::string& output) -{ +int CmdUDAs::execute(std::string& output) { int rc = 0; std::stringstream out; - std::vector udas; - for (auto& name : Context::getContext ().config) - { - if (name.first.substr (0, 4) == "uda." && - name.first.find (".type") != std::string::npos) - { - auto period = name.first.find ('.', 4); - if (period != std::string::npos) - udas.push_back (name.first.substr (4, period - 4)); + std::vector udas; + for (auto& name : Context::getContext().config) { + if (name.first.substr(0, 4) == "uda." && name.first.find(".type") != std::string::npos) { + auto period = name.first.find('.', 4); + if (period != std::string::npos) udas.push_back(name.first.substr(4, period - 4)); } } // Apply filter. Filter filter; - std::vector filtered; - filter.subset (filtered); + std::vector filtered; + filter.subset(filtered); - if (udas.size ()) - { - std::sort (udas.begin (), udas.end ()); + if (udas.size()) { + std::sort(udas.begin(), udas.end()); // Render a list of UDA name, type, label, allowed values, // possible default value, and finally the usage count. Table table; - table.width (Context::getContext ().getWidth ()); - table.add ("Name"); - table.add ("Type"); - table.add ("Label"); - table.add ("Allowed Values"); - table.add ("Default"); - table.add ("Usage Count"); - setHeaderUnderline (table); + table.width(Context::getContext().getWidth()); + table.add("Name"); + table.add("Type"); + table.add("Label"); + table.add("Allowed Values"); + table.add("Default"); + table.add("Usage Count"); + setHeaderUnderline(table); - for (auto& uda : udas) - { - std::string type = Context::getContext ().config.get ("uda." + uda + ".type"); - std::string label = Context::getContext ().config.get ("uda." + uda + ".label"); - std::string values = Context::getContext ().config.get ("uda." + uda + ".values"); - std::string defval = Context::getContext ().config.get ("uda." + uda + ".default"); - if (label == "") - label = uda; + for (auto& uda : udas) { + std::string type = Context::getContext().config.get("uda." + uda + ".type"); + std::string label = Context::getContext().config.get("uda." + uda + ".label"); + std::string values = Context::getContext().config.get("uda." + uda + ".values"); + std::string defval = Context::getContext().config.get("uda." + uda + ".default"); + if (label == "") label = uda; // Count UDA usage by UDA. int count = 0; for (auto& i : filtered) - if (i.has (uda)) - ++count; + if (i.has(uda)) ++count; - int row = table.addRow (); - table.set (row, 0, uda); - table.set (row, 1, type); - table.set (row, 2, label); - table.set (row, 3, values); - table.set (row, 4, defval); - table.set (row, 5, count); + int row = table.addRow(); + table.set(row, 0, uda); + table.set(row, 1, type); + table.set(row, 2, label); + table.set(row, 3, values); + table.set(row, 4, defval); + table.set(row, 5, count); } - out << optionalBlankLine () - << table.render () - << optionalBlankLine () - << (udas.size () == 1 - ? format ("{1} UDA defined", udas.size ()) - : format ("{1} UDAs defined", udas.size ())) + out << optionalBlankLine() << table.render() << optionalBlankLine() + << (udas.size() == 1 ? format("{1} UDA defined", udas.size()) + : format("{1} UDAs defined", udas.size())) << '\n'; - } - else - { + } else { out << "No UDAs defined.\n"; rc = 1; } // Orphans are task attributes that are not represented in context.columns. - std::map orphans; - for (auto& i : filtered) - { - for (auto& att : i.getUDAOrphans ()) - orphans[att]++; + std::map orphans; + for (auto& i : filtered) { + for (auto& att : i.getUDAOrphans()) orphans[att]++; } - if (orphans.size ()) - { + if (orphans.size()) { // Display the orphans and their counts. Table orphanTable; - orphanTable.width (Context::getContext ().getWidth ()); - orphanTable.add ("Orphan UDA"); - orphanTable.add ("Usage Count"); - setHeaderUnderline (orphanTable); + orphanTable.width(Context::getContext().getWidth()); + orphanTable.add("Orphan UDA"); + orphanTable.add("Usage Count"); + setHeaderUnderline(orphanTable); - for (auto& o : orphans) - { - int row = orphanTable.addRow (); - orphanTable.set (row, 0, o.first); - orphanTable.set (row, 1, o.second); + for (auto& o : orphans) { + int row = orphanTable.addRow(); + orphanTable.set(row, 0, o.first); + orphanTable.set(row, 1, o.second); } - out << optionalBlankLine () - << orphanTable.render () - << optionalBlankLine () - << (udas.size () == 1 - ? format ("{1} Orphan UDA", orphans.size ()) - : format ("{1} Orphan UDAs", orphans.size ())) + out << optionalBlankLine() << orphanTable.render() << optionalBlankLine() + << (udas.size() == 1 ? format("{1} Orphan UDA", orphans.size()) + : format("{1} Orphan UDAs", orphans.size())) << '\n'; } - output = out.str (); + output = out.str(); return rc; } /////////////////////////////////////////////////////////////////////////////// -CmdCompletionUDAs::CmdCompletionUDAs () -{ - _keyword = "_udas"; - _usage = "task _udas"; - _description = "Shows the defined UDAs for completion purposes"; - _read_only = true; - _displays_id = false; - _needs_gc = false; - _uses_context = false; - _accepts_filter = false; +CmdCompletionUDAs::CmdCompletionUDAs() { + _keyword = "_udas"; + _usage = "task _udas"; + _description = "Shows the defined UDAs for completion purposes"; + _read_only = true; + _displays_id = false; + _needs_gc = false; + _uses_context = false; + _accepts_filter = false; _accepts_modifications = false; _accepts_miscellaneous = false; - _category = Command::Category::internal; + _category = Command::Category::internal; } //////////////////////////////////////////////////////////////////////////////// -int CmdCompletionUDAs::execute (std::string& output) -{ - std::vector udas; - for (auto& name : Context::getContext ().config) - { - if (name.first.substr (0, 4) == "uda." && - name.first.find (".type") != std::string::npos) - { - auto period = name.first.find ('.', 4); - if (period != std::string::npos) - udas.push_back (name.first.substr (4, period - 4)); +int CmdCompletionUDAs::execute(std::string& output) { + std::vector udas; + for (auto& name : Context::getContext().config) { + if (name.first.substr(0, 4) == "uda." && name.first.find(".type") != std::string::npos) { + auto period = name.first.find('.', 4); + if (period != std::string::npos) udas.push_back(name.first.substr(4, period - 4)); } } - if (udas.size ()) - { - std::sort (udas.begin (), udas.end ()); - output = join ("\n", udas) + '\n'; + if (udas.size()) { + std::sort(udas.begin(), udas.end()); + output = join("\n", udas) + '\n'; } return 0; diff --git a/src/commands/CmdUDAs.h b/src/commands/CmdUDAs.h index ac2fb3bc0..185036ecd 100644 --- a/src/commands/CmdUDAs.h +++ b/src/commands/CmdUDAs.h @@ -27,21 +27,20 @@ #ifndef INCLUDED_CMDUDAS #define INCLUDED_CMDUDAS -#include #include -class CmdUDAs : public Command -{ -public: - CmdUDAs (); - int execute (std::string&); +#include + +class CmdUDAs : public Command { + public: + CmdUDAs(); + int execute(std::string&); }; -class CmdCompletionUDAs : public Command -{ -public: - CmdCompletionUDAs (); - int execute (std::string&); +class CmdCompletionUDAs : public Command { + public: + CmdCompletionUDAs(); + int execute(std::string&); }; #endif diff --git a/src/commands/CmdUndo.cpp b/src/commands/CmdUndo.cpp index cb3ec26c4..b462ae590 100644 --- a/src/commands/CmdUndo.cpp +++ b/src/commands/CmdUndo.cpp @@ -31,25 +31,23 @@ #include //////////////////////////////////////////////////////////////////////////////// -CmdUndo::CmdUndo () -{ - _keyword = "undo"; - _usage = "task undo"; - _description = "Reverts the most recent change to a task"; - _read_only = false; - _displays_id = false; - _needs_gc = false; - _uses_context = false; - _accepts_filter = false; +CmdUndo::CmdUndo() { + _keyword = "undo"; + _usage = "task undo"; + _description = "Reverts the most recent change to a task"; + _read_only = false; + _displays_id = false; + _needs_gc = false; + _uses_context = false; + _accepts_filter = false; _accepts_modifications = false; _accepts_miscellaneous = false; - _category = Command::Category::operation; + _category = Command::Category::operation; } //////////////////////////////////////////////////////////////////////////////// -int CmdUndo::execute (std::string&) -{ - Context::getContext ().tdb2.revert (); +int CmdUndo::execute(std::string&) { + Context::getContext().tdb2.revert(); return 0; } diff --git a/src/commands/CmdUndo.h b/src/commands/CmdUndo.h index ca2a0dce1..40993311f 100644 --- a/src/commands/CmdUndo.h +++ b/src/commands/CmdUndo.h @@ -27,14 +27,14 @@ #ifndef INCLUDED_CMDUNDO #define INCLUDED_CMDUNDO -#include #include -class CmdUndo : public Command -{ -public: - CmdUndo (); - int execute (std::string&); +#include + +class CmdUndo : public Command { + public: + CmdUndo(); + int execute(std::string&); }; #endif diff --git a/src/commands/CmdUnique.cpp b/src/commands/CmdUnique.cpp index ca67b3075..6833afb24 100644 --- a/src/commands/CmdUnique.cpp +++ b/src/commands/CmdUnique.cpp @@ -28,71 +28,63 @@ // cmake.h include header must come first #include -#include -#include #include #include #include +#include +#include + //////////////////////////////////////////////////////////////////////////////// -CmdUnique::CmdUnique () -{ - _keyword = "_unique"; - _usage = "task _unique "; - _description = "Generates lists of unique attribute values"; - _read_only = true; - _displays_id = true; - _needs_gc = true; - _uses_context = false; - _accepts_filter = true; +CmdUnique::CmdUnique() { + _keyword = "_unique"; + _usage = "task _unique "; + _description = "Generates lists of unique attribute values"; + _read_only = true; + _displays_id = true; + _needs_gc = true; + _uses_context = false; + _accepts_filter = true; _accepts_modifications = false; _accepts_miscellaneous = true; - _category = Command::Category::internal; + _category = Command::Category::internal; } //////////////////////////////////////////////////////////////////////////////// -int CmdUnique::execute (std::string& output) -{ +int CmdUnique::execute(std::string& output) { // Apply filter. Filter filter; - filter.disableSafety (); - std::vector filtered; - filter.subset (filtered); + filter.disableSafety(); + std::vector filtered; + filter.subset(filtered); // Find . - std::string attribute {}; + std::string attribute{}; // Just the first arg. - auto words = Context::getContext ().cli2.getWords (); - if (words.size () == 0) - throw std::string ("An attribute must be specified. See 'task _columns'."); + auto words = Context::getContext().cli2.getWords(); + if (words.size() == 0) throw std::string("An attribute must be specified. See 'task _columns'."); attribute = words[0]; std::string canonical; - if (! Context::getContext ().cli2.canonicalize (canonical, "attribute", attribute)) - throw std::string ("You must specify an attribute or UDA."); + if (!Context::getContext().cli2.canonicalize(canonical, "attribute", attribute)) + throw std::string("You must specify an attribute or UDA."); // Find the unique set of matching tasks. - std::set values; - for (auto& task : filtered) - { - if (task.has (canonical)) - { - values.insert (task.get (canonical)); - } - else if (canonical == "id" && - task.getStatus () != Task::deleted && - task.getStatus () != Task::completed) - { - values.insert (format (task.id)); + std::set values; + for (auto& task : filtered) { + if (task.has(canonical)) { + values.insert(task.get(canonical)); + } else if (canonical == "id" && task.getStatus() != Task::deleted && + task.getStatus() != Task::completed) { + values.insert(format(task.id)); } } // Generate list of values. - for (auto& value : values) - output += value + '\n'; + for (auto& value : values) output += value + '\n'; - Context::getContext ().headers.clear (); + Context::getContext().headers.clear(); return 0; } diff --git a/src/commands/CmdUnique.h b/src/commands/CmdUnique.h index cbe4b9d61..cad5f8405 100644 --- a/src/commands/CmdUnique.h +++ b/src/commands/CmdUnique.h @@ -27,14 +27,14 @@ #ifndef INCLUDED_CMDUNIQUE #define INCLUDED_CMDUNIQUE -#include #include -class CmdUnique : public Command -{ -public: - CmdUnique (); - int execute (std::string&); +#include + +class CmdUnique : public Command { + public: + CmdUnique(); + int execute(std::string&); }; #endif diff --git a/src/commands/CmdUrgency.cpp b/src/commands/CmdUrgency.cpp index 6260d8d2c..4d2b4a31f 100644 --- a/src/commands/CmdUrgency.cpp +++ b/src/commands/CmdUrgency.cpp @@ -28,55 +28,51 @@ // cmake.h include header must come first #include -#include -#include #include #include #include -#include #include +#include +#include + +#include //////////////////////////////////////////////////////////////////////////////// -CmdUrgency::CmdUrgency () -{ - _keyword = "_urgency"; - _usage = "task _urgency"; - _description = "Displays the urgency measure of a task"; - _read_only = true; - _displays_id = false; - _needs_gc = true; - _uses_context = false; - _accepts_filter = true; +CmdUrgency::CmdUrgency() { + _keyword = "_urgency"; + _usage = "task _urgency"; + _description = "Displays the urgency measure of a task"; + _read_only = true; + _displays_id = false; + _needs_gc = true; + _uses_context = false; + _accepts_filter = true; _accepts_modifications = false; _accepts_miscellaneous = false; - _category = Command::Category::internal; + _category = Command::Category::internal; } //////////////////////////////////////////////////////////////////////////////// -int CmdUrgency::execute (std::string& output) -{ +int CmdUrgency::execute(std::string& output) { // Apply filter. Filter filter; - std::vector filtered; - filter.subset (filtered); + std::vector filtered; + filter.subset(filtered); - if (filtered.size () == 0) - { - Context::getContext ().footnote ("No tasks specified."); + if (filtered.size() == 0) { + Context::getContext().footnote("No tasks specified."); return 1; } // Display urgency for the selected tasks. std::stringstream out; - for (auto& task : filtered) - { - out << format ("task {1} urgency {2}", - task.identifier (), - Lexer::trim (format (task.urgency (), 6, 3))) + for (auto& task : filtered) { + out << format("task {1} urgency {2}", task.identifier(), + Lexer::trim(format(task.urgency(), 6, 3))) << '\n'; } - output = out.str (); + output = out.str(); return 0; } diff --git a/src/commands/CmdUrgency.h b/src/commands/CmdUrgency.h index aeaad047d..b2be3256e 100644 --- a/src/commands/CmdUrgency.h +++ b/src/commands/CmdUrgency.h @@ -27,14 +27,14 @@ #ifndef INCLUDED_CMDURGENCY #define INCLUDED_CMDURGENCY -#include #include -class CmdUrgency : public Command -{ -public: - CmdUrgency (); - int execute (std::string&); +#include + +class CmdUrgency : public Command { + public: + CmdUrgency(); + int execute(std::string&); }; #endif diff --git a/src/commands/CmdVersion.cpp b/src/commands/CmdVersion.cpp index 1042071d6..fd82bda98 100644 --- a/src/commands/CmdVersion.cpp +++ b/src/commands/CmdVersion.cpp @@ -28,97 +28,90 @@ // cmake.h include header must come first #include -#include -#include -#include #include +#include #include +#include + +#include #ifdef HAVE_COMMIT #include #endif -#include #include +#include //////////////////////////////////////////////////////////////////////////////// -CmdVersion::CmdVersion () -{ - _keyword = "version"; - _usage = "task version"; - _description = "Shows the Taskwarrior version number"; - _read_only = true; - _displays_id = false; - _needs_gc = false; - _uses_context = false; - _accepts_filter = false; +CmdVersion::CmdVersion() { + _keyword = "version"; + _usage = "task version"; + _description = "Shows the Taskwarrior version number"; + _read_only = true; + _displays_id = false; + _needs_gc = false; + _uses_context = false; + _accepts_filter = false; _accepts_modifications = false; _accepts_miscellaneous = false; - _category = Command::Category::misc; + _category = Command::Category::misc; } //////////////////////////////////////////////////////////////////////////////// -int CmdVersion::execute (std::string& output) -{ +int CmdVersion::execute(std::string& output) { std::stringstream out; // Create a table for the disclaimer. - int width = Context::getContext ().getWidth (); + int width = Context::getContext().getWidth(); Table disclaimer; - disclaimer.width (width); - disclaimer.add (""); - disclaimer.set (disclaimer.addRow (), 0, "Taskwarrior may be copied only under the terms of the MIT license, which may be found in the Taskwarrior source kit."); + disclaimer.width(width); + disclaimer.add(""); + disclaimer.set(disclaimer.addRow(), 0, + "Taskwarrior may be copied only under the terms of the MIT license, which may be " + "found in the Taskwarrior source kit."); // Create a table for the URL. Table link; - link.width (width); - link.add (""); - link.set (link.addRow (), 0, "Documentation for Taskwarrior can be found using 'man task', 'man taskrc', 'man task-color', 'man task-sync' or at https://taskwarrior.org"); + link.width(width); + link.add(""); + link.set(link.addRow(), 0, + "Documentation for Taskwarrior can be found using 'man task', 'man taskrc', 'man " + "task-color', 'man task-sync' or at https://taskwarrior.org"); Datetime now; Color bold; - if (Context::getContext ().color ()) - bold = Color ("bold"); + if (Context::getContext().color()) bold = Color("bold"); out << '\n' - << format ("{1} {2} built for ", bold.colorize (PACKAGE), bold.colorize (VERSION)) - << osName () + << format("{1} {2} built for ", bold.colorize(PACKAGE), bold.colorize(VERSION)) << osName() << '\n' - << "Copyright (C) 2006 - " << now.year () << " T. Babej, P. Beckingham, F. Hernandez." + << "Copyright (C) 2006 - " << now.year() << " T. Babej, P. Beckingham, F. Hernandez." << '\n' << '\n' - << '\n' - << disclaimer.render () - << '\n' - << link.render () - << '\n'; + << disclaimer.render() << '\n' + << link.render() << '\n'; - output = out.str (); + output = out.str(); return 0; } //////////////////////////////////////////////////////////////////////////////// -CmdCompletionVersion::CmdCompletionVersion () -{ - _keyword = "_version"; - _usage = "task _version"; - _description = "Shows only the Taskwarrior version number"; - _read_only = true; - _displays_id = false; - _needs_gc = false; - _uses_context = false; - _accepts_filter = false; +CmdCompletionVersion::CmdCompletionVersion() { + _keyword = "_version"; + _usage = "task _version"; + _description = "Shows only the Taskwarrior version number"; + _read_only = true; + _displays_id = false; + _needs_gc = false; + _uses_context = false; + _accepts_filter = false; _accepts_modifications = false; _accepts_miscellaneous = false; - _category = Command::Category::internal; + _category = Command::Category::internal; } //////////////////////////////////////////////////////////////////////////////// -int CmdCompletionVersion::execute (std::string& output) -{ +int CmdCompletionVersion::execute(std::string& output) { #ifdef HAVE_COMMIT - output = std::string (VERSION) - + std::string (" (") - + std::string (COMMIT) - + std::string (")"); + output = std::string(VERSION) + std::string(" (") + std::string(COMMIT) + std::string(")"); #else output = VERSION; #endif diff --git a/src/commands/CmdVersion.h b/src/commands/CmdVersion.h index 9a1ef26e2..1c7e6233e 100644 --- a/src/commands/CmdVersion.h +++ b/src/commands/CmdVersion.h @@ -27,21 +27,20 @@ #ifndef INCLUDED_CMDVERSION #define INCLUDED_CMDVERSION -#include #include -class CmdVersion : public Command -{ -public: - CmdVersion (); - int execute (std::string&); +#include + +class CmdVersion : public Command { + public: + CmdVersion(); + int execute(std::string&); }; -class CmdCompletionVersion : public Command -{ -public: - CmdCompletionVersion (); - int execute (std::string&); +class CmdCompletionVersion : public Command { + public: + CmdCompletionVersion(); + int execute(std::string&); }; #endif diff --git a/src/commands/Command.cpp b/src/commands/Command.cpp index ba028b4a9..0dc215b01 100644 --- a/src/commands/Command.cpp +++ b/src/commands/Command.cpp @@ -27,15 +27,6 @@ #include // cmake.h include header must come first -#include -#include -#include -#include -#include -#include -#include -#include - #include #include #include @@ -57,6 +48,15 @@ #include #include #include +#include +#include +#include +#include +#include +#include + +#include +#include #ifdef HAVE_EXECUTE #include #endif @@ -88,222 +88,251 @@ #include #include #include - -#include -#include #include +#include +#include //////////////////////////////////////////////////////////////////////////////// -void Command::factory (std::map & all) -{ +void Command::factory(std::map& all) { Command* c; - c = new CmdAdd (); all[c->keyword ()] = c; - c = new CmdAnnotate (); all[c->keyword ()] = c; - c = new CmdAppend (); all[c->keyword ()] = c; - c = new CmdBurndownDaily (); all[c->keyword ()] = c; - c = new CmdBurndownMonthly (); all[c->keyword ()] = c; - c = new CmdBurndownWeekly (); all[c->keyword ()] = c; - c = new CmdCalc (); all[c->keyword ()] = c; - c = new CmdCalendar (); all[c->keyword ()] = c; - c = new CmdColor (); all[c->keyword ()] = c; - c = new CmdColumns (); all[c->keyword ()] = c; - c = new CmdCommands (); all[c->keyword ()] = c; - c = new CmdCompletionAliases (); all[c->keyword ()] = c; - c = new CmdCompletionColumns (); all[c->keyword ()] = c; - c = new CmdCompletionCommands (); all[c->keyword ()] = c; - c = new CmdCompletionConfig (); all[c->keyword ()] = c; - c = new CmdCompletionContext (); all[c->keyword ()] = c; - c = new CmdCompletionIds (); all[c->keyword ()] = c; - c = new CmdCompletionUDAs (); all[c->keyword ()] = c; - c = new CmdCompletionUuids (); all[c->keyword ()] = c; - c = new CmdCompletionProjects (); all[c->keyword ()] = c; - c = new CmdCompletionTags (); all[c->keyword ()] = c; - c = new CmdCompletionVersion (); all[c->keyword ()] = c; - c = new CmdConfig (); all[c->keyword ()] = c; - c = new CmdContext (); all[c->keyword ()] = c; - c = new CmdCount (); all[c->keyword ()] = c; - c = new CmdDelete (); all[c->keyword ()] = c; - c = new CmdDenotate (); all[c->keyword ()] = c; - c = new CmdDiagnostics (); all[c->keyword ()] = c; - c = new CmdDone (); all[c->keyword ()] = c; - c = new CmdDuplicate (); all[c->keyword ()] = c; - c = new CmdEdit (); all[c->keyword ()] = c; + c = new CmdAdd(); + all[c->keyword()] = c; + c = new CmdAnnotate(); + all[c->keyword()] = c; + c = new CmdAppend(); + all[c->keyword()] = c; + c = new CmdBurndownDaily(); + all[c->keyword()] = c; + c = new CmdBurndownMonthly(); + all[c->keyword()] = c; + c = new CmdBurndownWeekly(); + all[c->keyword()] = c; + c = new CmdCalc(); + all[c->keyword()] = c; + c = new CmdCalendar(); + all[c->keyword()] = c; + c = new CmdColor(); + all[c->keyword()] = c; + c = new CmdColumns(); + all[c->keyword()] = c; + c = new CmdCommands(); + all[c->keyword()] = c; + c = new CmdCompletionAliases(); + all[c->keyword()] = c; + c = new CmdCompletionColumns(); + all[c->keyword()] = c; + c = new CmdCompletionCommands(); + all[c->keyword()] = c; + c = new CmdCompletionConfig(); + all[c->keyword()] = c; + c = new CmdCompletionContext(); + all[c->keyword()] = c; + c = new CmdCompletionIds(); + all[c->keyword()] = c; + c = new CmdCompletionUDAs(); + all[c->keyword()] = c; + c = new CmdCompletionUuids(); + all[c->keyword()] = c; + c = new CmdCompletionProjects(); + all[c->keyword()] = c; + c = new CmdCompletionTags(); + all[c->keyword()] = c; + c = new CmdCompletionVersion(); + all[c->keyword()] = c; + c = new CmdConfig(); + all[c->keyword()] = c; + c = new CmdContext(); + all[c->keyword()] = c; + c = new CmdCount(); + all[c->keyword()] = c; + c = new CmdDelete(); + all[c->keyword()] = c; + c = new CmdDenotate(); + all[c->keyword()] = c; + c = new CmdDiagnostics(); + all[c->keyword()] = c; + c = new CmdDone(); + all[c->keyword()] = c; + c = new CmdDuplicate(); + all[c->keyword()] = c; + c = new CmdEdit(); + all[c->keyword()] = c; #ifdef HAVE_EXECUTE - c = new CmdExec (); all[c->keyword ()] = c; + c = new CmdExec(); + all[c->keyword()] = c; #endif - c = new CmdExport (); all[c->keyword ()] = c; - c = new CmdGet (); all[c->keyword ()] = c; - c = new CmdGHistoryDaily (); all[c->keyword ()] = c; - c = new CmdGHistoryWeekly (); all[c->keyword ()] = c; - c = new CmdGHistoryMonthly (); all[c->keyword ()] = c; - c = new CmdGHistoryAnnual (); all[c->keyword ()] = c; - c = new CmdHelp (); all[c->keyword ()] = c; - c = new CmdHistoryDaily (); all[c->keyword ()] = c; - c = new CmdHistoryWeekly (); all[c->keyword ()] = c; - c = new CmdHistoryMonthly (); all[c->keyword ()] = c; - c = new CmdHistoryAnnual (); all[c->keyword ()] = c; - c = new CmdIDs (); all[c->keyword ()] = c; - c = new CmdImport (); all[c->keyword ()] = c; - c = new CmdInfo (); all[c->keyword ()] = c; - c = new CmdLog (); all[c->keyword ()] = c; - c = new CmdLogo (); all[c->keyword ()] = c; - c = new CmdModify (); all[c->keyword ()] = c; - c = new CmdNews (); all[c->keyword ()] = c; - c = new CmdPrepend (); all[c->keyword ()] = c; - c = new CmdProjects (); all[c->keyword ()] = c; - c = new CmdPurge (); all[c->keyword ()] = c; - c = new CmdReports (); all[c->keyword ()] = c; - c = new CmdShow (); all[c->keyword ()] = c; - c = new CmdShowRaw (); all[c->keyword ()] = c; - c = new CmdStart (); all[c->keyword ()] = c; - c = new CmdStats (); all[c->keyword ()] = c; - c = new CmdStop (); all[c->keyword ()] = c; - c = new CmdSummary (); all[c->keyword ()] = c; - c = new CmdSync (); all[c->keyword ()] = c; - c = new CmdTags (); all[c->keyword ()] = c; - c = new CmdTimesheet (); all[c->keyword ()] = c; - c = new CmdUDAs (); all[c->keyword ()] = c; - c = new CmdUndo (); all[c->keyword ()] = c; - c = new CmdUnique (); all[c->keyword ()] = c; - c = new CmdUrgency (); all[c->keyword ()] = c; - c = new CmdUUIDs (); all[c->keyword ()] = c; - c = new CmdVersion (); all[c->keyword ()] = c; - c = new CmdZshAttributes (); all[c->keyword ()] = c; - c = new CmdZshCommands (); all[c->keyword ()] = c; - c = new CmdZshCompletionIds (); all[c->keyword ()] = c; - c = new CmdZshCompletionUuids (); all[c->keyword ()] = c; + c = new CmdExport(); + all[c->keyword()] = c; + c = new CmdGet(); + all[c->keyword()] = c; + c = new CmdGHistoryDaily(); + all[c->keyword()] = c; + c = new CmdGHistoryWeekly(); + all[c->keyword()] = c; + c = new CmdGHistoryMonthly(); + all[c->keyword()] = c; + c = new CmdGHistoryAnnual(); + all[c->keyword()] = c; + c = new CmdHelp(); + all[c->keyword()] = c; + c = new CmdHistoryDaily(); + all[c->keyword()] = c; + c = new CmdHistoryWeekly(); + all[c->keyword()] = c; + c = new CmdHistoryMonthly(); + all[c->keyword()] = c; + c = new CmdHistoryAnnual(); + all[c->keyword()] = c; + c = new CmdIDs(); + all[c->keyword()] = c; + c = new CmdImport(); + all[c->keyword()] = c; + c = new CmdInfo(); + all[c->keyword()] = c; + c = new CmdLog(); + all[c->keyword()] = c; + c = new CmdLogo(); + all[c->keyword()] = c; + c = new CmdModify(); + all[c->keyword()] = c; + c = new CmdNews(); + all[c->keyword()] = c; + c = new CmdPrepend(); + all[c->keyword()] = c; + c = new CmdProjects(); + all[c->keyword()] = c; + c = new CmdPurge(); + all[c->keyword()] = c; + c = new CmdReports(); + all[c->keyword()] = c; + c = new CmdShow(); + all[c->keyword()] = c; + c = new CmdShowRaw(); + all[c->keyword()] = c; + c = new CmdStart(); + all[c->keyword()] = c; + c = new CmdStats(); + all[c->keyword()] = c; + c = new CmdStop(); + all[c->keyword()] = c; + c = new CmdSummary(); + all[c->keyword()] = c; + c = new CmdSync(); + all[c->keyword()] = c; + c = new CmdTags(); + all[c->keyword()] = c; + c = new CmdTimesheet(); + all[c->keyword()] = c; + c = new CmdUDAs(); + all[c->keyword()] = c; + c = new CmdUndo(); + all[c->keyword()] = c; + c = new CmdUnique(); + all[c->keyword()] = c; + c = new CmdUrgency(); + all[c->keyword()] = c; + c = new CmdUUIDs(); + all[c->keyword()] = c; + c = new CmdVersion(); + all[c->keyword()] = c; + c = new CmdZshAttributes(); + all[c->keyword()] = c; + c = new CmdZshCommands(); + all[c->keyword()] = c; + c = new CmdZshCompletionIds(); + all[c->keyword()] = c; + c = new CmdZshCompletionUuids(); + all[c->keyword()] = c; // Instantiate a command object for each custom report. - std::vector reports; - for (auto &i : Context::getContext ().config) - { - if (i.first.substr (0, 7) == "report.") - { - std::string report = i.first.substr (7); - auto columns = report.find (".columns"); - if (columns != std::string::npos) - reports.push_back (report.substr (0, columns)); + std::vector reports; + for (auto& i : Context::getContext().config) { + if (i.first.substr(0, 7) == "report.") { + std::string report = i.first.substr(7); + auto columns = report.find(".columns"); + if (columns != std::string::npos) reports.push_back(report.substr(0, columns)); } } - for (auto &report : reports) - { + for (auto& report : reports) { // Make sure a custom report does not clash with a built-in command. - if (all.find (report) != all.end ()) - throw format ("Custom report '{1}' conflicts with built-in task command.", report); + if (all.find(report) != all.end()) + throw format("Custom report '{1}' conflicts with built-in task command.", report); - c = new CmdCustom ( - report, - "task " + report, - Context::getContext ().config.get ("report." + report + ".description")); + c = new CmdCustom(report, "task " + report, + Context::getContext().config.get("report." + report + ".description")); - all[c->keyword ()] = c; + all[c->keyword()] = c; } } //////////////////////////////////////////////////////////////////////////////// -const std::map Command::categoryNames = -{ - // These strings are intentionally not l10n'd: they are used as identifiers. - {Command::Category::unassigned, "unassigned"} // should never happen - ,{Command::Category::metadata, "metadata"} - ,{Command::Category::report, "report"} - ,{Command::Category::operation, "operation"} - ,{Command::Category::context, "context"} - ,{Command::Category::graphs, "graphs" } - ,{Command::Category::config, "config" } - ,{Command::Category::migration, "migration"} - ,{Command::Category::misc, "misc" } - ,{Command::Category::internal, "internal"} - ,{Command::Category::UNDOCUMENTED, "undocumented"} -}; +const std::map Command::categoryNames = { + // These strings are intentionally not l10n'd: they are used as identifiers. + {Command::Category::unassigned, "unassigned"} // should never happen + , + {Command::Category::metadata, "metadata"}, + {Command::Category::report, "report"}, + {Command::Category::operation, "operation"}, + {Command::Category::context, "context"}, + {Command::Category::graphs, "graphs"}, + {Command::Category::config, "config"}, + {Command::Category::migration, "migration"}, + {Command::Category::misc, "misc"}, + {Command::Category::internal, "internal"}, + {Command::Category::UNDOCUMENTED, "undocumented"}}; //////////////////////////////////////////////////////////////////////////////// -Command::Command () -: _keyword ("") -, _usage ("") -, _description ("") -, _read_only (true) -, _displays_id (true) -, _needs_confirm (false) -, _needs_gc (true) -, _uses_context (false) -, _accepts_filter (false) -, _accepts_modifications (false) -, _accepts_miscellaneous (false) -, _category(Category::unassigned) -, _permission_quit (false) -, _permission_all (false) -, _first_iteration (true) -{ -} +Command::Command() + : _keyword(""), + _usage(""), + _description(""), + _read_only(true), + _displays_id(true), + _needs_confirm(false), + _needs_gc(true), + _uses_context(false), + _accepts_filter(false), + _accepts_modifications(false), + _accepts_miscellaneous(false), + _category(Category::unassigned), + _permission_quit(false), + _permission_all(false), + _first_iteration(true) {} //////////////////////////////////////////////////////////////////////////////// -std::string Command::keyword () const -{ - return _keyword; -} +std::string Command::keyword() const { return _keyword; } //////////////////////////////////////////////////////////////////////////////// -std::string Command::usage () const -{ - return _usage; -} +std::string Command::usage() const { return _usage; } //////////////////////////////////////////////////////////////////////////////// -std::string Command::description () const -{ - return _description; -} +std::string Command::description() const { return _description; } //////////////////////////////////////////////////////////////////////////////// -bool Command::read_only () const -{ - return _read_only; -} +bool Command::read_only() const { return _read_only; } //////////////////////////////////////////////////////////////////////////////// -bool Command::displays_id () const -{ - return _displays_id; -} +bool Command::displays_id() const { return _displays_id; } //////////////////////////////////////////////////////////////////////////////// -bool Command::needs_gc () const -{ - return _needs_gc; -} +bool Command::needs_gc() const { return _needs_gc; } //////////////////////////////////////////////////////////////////////////////// -bool Command::uses_context () const -{ - return _uses_context; -} +bool Command::uses_context() const { return _uses_context; } //////////////////////////////////////////////////////////////////////////////// -bool Command::accepts_filter () const -{ - return _accepts_filter; -} +bool Command::accepts_filter() const { return _accepts_filter; } //////////////////////////////////////////////////////////////////////////////// -bool Command::accepts_modifications () const -{ - return _accepts_modifications; -} +bool Command::accepts_modifications() const { return _accepts_modifications; } //////////////////////////////////////////////////////////////////////////////// -bool Command::accepts_miscellaneous () const -{ - return _accepts_miscellaneous; -} +bool Command::accepts_miscellaneous() const { return _accepts_miscellaneous; } //////////////////////////////////////////////////////////////////////////////// -Command::Category Command::category () const -{ - return _category; -} +Command::Category Command::category() const { return _category; } //////////////////////////////////////////////////////////////////////////////// // Returns true or false indicating whether to proceed with a write command, on @@ -314,51 +343,44 @@ Command::Category Command::category () const // rc.bulk // rc.confirmation // this->_read_only -bool Command::permission ( - const std::string& question, - unsigned int quantity) -{ +bool Command::permission(const std::string& question, unsigned int quantity) { // Read-only commands do not need to seek permission. Write commands are // granted permission automatically if the 'all' selection was made in an // earlier call. Or if the 'all' option has already been made. - if (_read_only || - _permission_all) - return true; + if (_read_only || _permission_all) return true; // If the 'quit' selection has already been made. - if (_permission_quit) - return false; + if (_permission_quit) return false; // What remains are write commands that have not yet selected 'all' or 'quit'. // Describe the task. - bool confirmation = Context::getContext ().config.getBoolean ("confirmation"); - unsigned int bulk = Context::getContext ().config.getInteger ("bulk"); + bool confirmation = Context::getContext().config.getBoolean("confirmation"); + unsigned int bulk = Context::getContext().config.getInteger("bulk"); // Quantity 1 modifications have optional confirmation, and only (y/n). - if (quantity == 1) - { - if (!_needs_confirm || - !confirmation) - return true; + if (quantity == 1) { + if (!_needs_confirm || !confirmation) return true; - bool answer = confirm (question); + bool answer = confirm(question); return answer; } // 1 < Quantity < bulk modifications have optional confirmation, in the (y/n/a/q) // style. Bulk = 0 denotes infinite bulk. - if ((bulk == 0 || quantity < bulk) && (!_needs_confirm || !confirmation)) - return true; + if ((bulk == 0 || quantity < bulk) && (!_needs_confirm || !confirmation)) return true; - if (Context::getContext ().verbose ("blank") && !_first_iteration) - std::cout << '\n'; - int answer = confirm4 (question); + if (Context::getContext().verbose("blank") && !_first_iteration) std::cout << '\n'; + int answer = confirm4(question); _first_iteration = false; - switch (answer) - { - case 1: return true; // yes - case 2: _permission_all = true; return true; // all - case 3: _permission_quit = true; return false; // quit + switch (answer) { + case 1: + return true; // yes + case 2: + _permission_all = true; + return true; // all + case 3: + _permission_quit = true; + return false; // quit } return false; // This line keeps the compiler happy. diff --git a/src/commands/Command.h b/src/commands/Command.h index d93dd90c3..43d6ced89 100644 --- a/src/commands/Command.h +++ b/src/commands/Command.h @@ -27,16 +27,15 @@ #ifndef INCLUDED_COMMAND #define INCLUDED_COMMAND -#include -#include -#include #include -class Command -{ -public: - enum class Category - { +#include +#include +#include + +class Command { + public: + enum class Category { unassigned, // In presentation ("usefulness") order: frequently-used categories first. metadata, @@ -52,46 +51,46 @@ public: // Whenever you extend this enum, update categoryNames. }; - Command (); - virtual ~Command () = default; + Command(); + virtual ~Command() = default; - static void factory (std::map &); + static void factory(std::map&); - std::string keyword () const; - std::string usage () const; - std::string description () const; - bool read_only () const; - bool displays_id () const; - bool needs_gc () const; - virtual bool uses_context () const; - bool accepts_filter () const; - bool accepts_modifications () const; - bool accepts_miscellaneous () const; - Category category () const; - virtual int execute (std::string&) = 0; + std::string keyword() const; + std::string usage() const; + std::string description() const; + bool read_only() const; + bool displays_id() const; + bool needs_gc() const; + virtual bool uses_context() const; + bool accepts_filter() const; + bool accepts_modifications() const; + bool accepts_miscellaneous() const; + Category category() const; + virtual int execute(std::string&) = 0; -protected: - bool permission (const std::string&, unsigned int); - static const std::map categoryNames; + protected: + bool permission(const std::string&, unsigned int); + static const std::map categoryNames; -protected: + protected: std::string _keyword; std::string _usage; std::string _description; - bool _read_only; - bool _displays_id; - bool _needs_confirm; - bool _needs_gc; - bool _uses_context; - bool _accepts_filter; - bool _accepts_modifications; - bool _accepts_miscellaneous; - Category _category; + bool _read_only; + bool _displays_id; + bool _needs_confirm; + bool _needs_gc; + bool _uses_context; + bool _accepts_filter; + bool _accepts_modifications; + bool _accepts_miscellaneous; + Category _category; // Permission support - bool _permission_quit; - bool _permission_all; - bool _first_iteration; + bool _permission_quit; + bool _permission_all; + bool _first_iteration; }; #endif diff --git a/src/dependency.cpp b/src/dependency.cpp index ab17c3d08..28b592470 100644 --- a/src/dependency.cpp +++ b/src/dependency.cpp @@ -27,62 +27,56 @@ #include // cmake.h include header must come first +#include +#include +#include +#include + #include #include #include #include -#include -#include -#include -#include -#define STRING_DEPEND_BLOCKED "Task {1} is blocked by:" +#define STRING_DEPEND_BLOCKED "Task {1} is blocked by:" //////////////////////////////////////////////////////////////////////////////// // Returns true if the supplied task adds a cycle to the dependency chain. -bool dependencyIsCircular (const Task& task) -{ +bool dependencyIsCircular(const Task& task) { // A new task has no UUID assigned yet, and therefore cannot be part of any // dependency chain. - if (task.has ("uuid")) - { - auto task_uuid = task.get ("uuid"); + if (task.has("uuid")) { + auto task_uuid = task.get("uuid"); - std::stack s; - s.push (task); + std::stack s; + s.push(task); - std::unordered_set visited; - visited.insert (task_uuid); + std::unordered_set visited; + visited.insert(task_uuid); - while (! s.empty ()) - { - Task& current = s.top (); - auto deps_current = current.getDependencyUUIDs (); + while (!s.empty()) { + Task& current = s.top(); + auto deps_current = current.getDependencyUUIDs(); // This is a basic depth first search that always terminates given the // fact that we do not visit any task twice - for (const auto& dep : deps_current) - { - if (Context::getContext ().tdb2.get (dep, current)) - { - auto current_uuid = current.get ("uuid"); + for (const auto& dep : deps_current) { + if (Context::getContext().tdb2.get(dep, current)) { + auto current_uuid = current.get("uuid"); - if (task_uuid == current_uuid) - { + if (task_uuid == current_uuid) { // Cycle found, initial task reached for the second time! return true; } - if (visited.find (current_uuid) == visited.end ()) - { + if (visited.find(current_uuid) == visited.end()) { // Push the task to the stack, if it has not been processed yet - s.push (current); - visited.insert (current_uuid); + s.push(current); + visited.insert(current_uuid); } } } - s.pop (); + s.pop(); } } @@ -118,76 +112,61 @@ bool dependencyIsCircular (const Task& task) // 1 dep:3,5 // 4 dep:3,5 // -void dependencyChainOnComplete (Task& task) -{ - auto blocking = task.getDependencyTasks (); +void dependencyChainOnComplete(Task& task) { + auto blocking = task.getDependencyTasks(); // If the task is anything but the tail end of a dependency chain. - if (blocking.size ()) - { - auto blocked = task.getBlockedTasks (); + if (blocking.size()) { + auto blocked = task.getBlockedTasks(); // Nag about broken chain. - if (Context::getContext ().config.getBoolean ("dependency.reminder")) - { - std::cout << format (STRING_DEPEND_BLOCKED, task.identifier ()) - << '\n'; + if (Context::getContext().config.getBoolean("dependency.reminder")) { + std::cout << format(STRING_DEPEND_BLOCKED, task.identifier()) << '\n'; for (const auto& b : blocking) - std::cout << " " << b.id << ' ' << b.get ("description") << '\n'; + std::cout << " " << b.id << ' ' << b.get("description") << '\n'; } // If there are both blocking and blocked tasks, the chain is broken. - if (blocked.size ()) - { - if (Context::getContext ().config.getBoolean ("dependency.reminder")) - { + if (blocked.size()) { + if (Context::getContext().config.getBoolean("dependency.reminder")) { std::cout << "and is blocking:\n"; for (const auto& b : blocked) - std::cout << " " << b.id << ' ' << b.get ("description") << '\n'; + std::cout << " " << b.id << ' ' << b.get("description") << '\n'; } - if (!Context::getContext ().config.getBoolean ("dependency.confirmation") || - confirm ("Would you like the dependency chain fixed?")) - { + if (!Context::getContext().config.getBoolean("dependency.confirmation") || + confirm("Would you like the dependency chain fixed?")) { // Repair the chain - everything in blocked should now depend on // everything in blocking, instead of task.id. - for (auto& left : blocked) - { - left.removeDependency (task.id); + for (auto& left : blocked) { + left.removeDependency(task.id); - for (const auto& right : blocking) - left.addDependency (right.id); + for (const auto& right : blocking) left.addDependency(right.id); } // Now update TDB2, now that the updates have all occurred. - for (auto& left : blocked) - Context::getContext ().tdb2.modify (left); + for (auto& left : blocked) Context::getContext().tdb2.modify(left); - for (auto& right : blocking) - Context::getContext ().tdb2.modify (right); + for (auto& right : blocking) Context::getContext().tdb2.modify(right); } } } } //////////////////////////////////////////////////////////////////////////////// -void dependencyChainOnStart (Task& task) -{ - if (Context::getContext ().config.getBoolean ("dependency.reminder")) - { - auto blocking = task.getDependencyTasks (); +void dependencyChainOnStart(Task& task) { + if (Context::getContext().config.getBoolean("dependency.reminder")) { + auto blocking = task.getDependencyTasks(); // If the task is anything but the tail end of a dependency chain, nag about // broken chain. - if (blocking.size ()) - { - std::cout << format (STRING_DEPEND_BLOCKED, task.identifier ()) - << '\n'; + if (blocking.size()) { + std::cout << format(STRING_DEPEND_BLOCKED, task.identifier()) << '\n'; for (const auto& b : blocking) - std::cout << " " << b.id << ' ' << b.get ("description") << '\n'; + std::cout << " " << b.id << ' ' << b.get("description") << '\n'; } } } diff --git a/src/feedback.cpp b/src/feedback.cpp index 4905b06d0..60d89a686 100644 --- a/src/feedback.cpp +++ b/src/feedback.cpp @@ -27,38 +27,34 @@ #include // cmake.h include header must come first -#include -#include -#include -#include -#include -#include -#include #include #include #include #include +#include +#include #include #include -#include +#include -static void countTasks (const std::vector &, const std::string&, int&, int&); +#include +#include +#include +#include +#include + +static void countTasks(const std::vector&, const std::string&, int&, int&); //////////////////////////////////////////////////////////////////////////////// -std::string renderAttribute (const std::string& name, const std::string& value, const std::string& format /* = "" */) -{ - if (Context::getContext ().columns.find (name) != Context::getContext ().columns.end ()) - { - Column* col = Context::getContext ().columns[name]; - if (col && - col->type () == "date" && - value != "") - { - Datetime d ((time_t)strtoll (value.c_str (), nullptr, 10)); - if (format == "") - return d.toString (Context::getContext ().config.get ("dateformat")); +std::string renderAttribute(const std::string& name, const std::string& value, + const std::string& format /* = "" */) { + if (Context::getContext().columns.find(name) != Context::getContext().columns.end()) { + Column* col = Context::getContext().columns[name]; + if (col && col->type() == "date" && value != "") { + Datetime d((time_t)strtoll(value.c_str(), nullptr, 10)); + if (format == "") return d.toString(Context::getContext().config.get("dateformat")); - return d.toString (format); + return d.toString(format); } } @@ -68,10 +64,8 @@ std::string renderAttribute (const std::string& name, const std::string& value, //////////////////////////////////////////////////////////////////////////////// // Implements: // -void feedback_affected (const std::string& effect) -{ - if (Context::getContext ().verbose ("affected")) - std::cout << effect << "\n"; +void feedback_affected(const std::string& effect) { + if (Context::getContext().verbose("affected")) std::cout << effect << "\n"; } //////////////////////////////////////////////////////////////////////////////// @@ -80,11 +74,8 @@ void feedback_affected (const std::string& effect) // // The 'effect' string should contain: // {1} Quantity -void feedback_affected (const std::string& effect, int quantity) -{ - if (Context::getContext ().verbose ("affected")) - std::cout << format (effect, quantity) - << "\n"; +void feedback_affected(const std::string& effect, int quantity) { + if (Context::getContext().verbose("affected")) std::cout << format(effect, quantity) << "\n"; } //////////////////////////////////////////////////////////////////////////////// @@ -94,76 +85,49 @@ void feedback_affected (const std::string& effect, int quantity) // The 'effect' string should contain: // {1} ID // {2} Description -void feedback_affected (const std::string& effect, const Task& task) -{ - if (Context::getContext ().verbose ("affected")) - { - std::cout << format (effect, - task.identifier (true), - task.get ("description")) - << "\n"; +void feedback_affected(const std::string& effect, const Task& task) { + if (Context::getContext().verbose("affected")) { + std::cout << format(effect, task.identifier(true), task.get("description")) << "\n"; } } //////////////////////////////////////////////////////////////////////////////// // Implements feedback and error when adding a reserved tag name. -void feedback_reserved_tags (const std::string& tag) -{ +void feedback_reserved_tags(const std::string& tag) { // Note: This list must match that in Task::hasTag. // Note: This list must match that in CmdInfo::execute. - if (tag == "ACTIVE" || - tag == "ANNOTATED" || - tag == "BLOCKED" || - tag == "BLOCKING" || - tag == "CHILD" || // Deprecated 2.6.0 - tag == "COMPLETED" || - tag == "DELETED" || - tag == "DUE" || - tag == "DUETODAY" || - tag == "INSTANCE" || - tag == "LATEST" || - tag == "MONTH" || - tag == "ORPHAN" || - tag == "OVERDUE" || - tag == "PARENT" || // Deprecated 2.6.0 - tag == "PENDING" || - tag == "PRIORITY" || - tag == "PROJECT" || - tag == "QUARTER" || - tag == "READY" || - tag == "SCHEDULED" || - tag == "TAGGED" || - tag == "TEMPLATE" || - tag == "TODAY" || - tag == "TOMORROW" || - tag == "UDA" || - tag == "UNBLOCKED" || - tag == "UNTIL" || - tag == "WAITING" || - tag == "WEEK" || - tag == "YEAR" || - tag == "YESTERDAY") - { - throw format ("Virtual tags (including '{1}') are reserved and may not be added or removed.", tag); + if (tag == "ACTIVE" || tag == "ANNOTATED" || tag == "BLOCKED" || tag == "BLOCKING" || + tag == "CHILD" || // Deprecated 2.6.0 + tag == "COMPLETED" || tag == "DELETED" || tag == "DUE" || tag == "DUETODAY" || + tag == "INSTANCE" || tag == "LATEST" || tag == "MONTH" || tag == "ORPHAN" || + tag == "OVERDUE" || tag == "PARENT" || // Deprecated 2.6.0 + tag == "PENDING" || tag == "PRIORITY" || tag == "PROJECT" || tag == "QUARTER" || + tag == "READY" || tag == "SCHEDULED" || tag == "TAGGED" || tag == "TEMPLATE" || + tag == "TODAY" || tag == "TOMORROW" || tag == "UDA" || tag == "UNBLOCKED" || tag == "UNTIL" || + tag == "WAITING" || tag == "WEEK" || tag == "YEAR" || tag == "YESTERDAY") { + throw format("Virtual tags (including '{1}') are reserved and may not be added or removed.", + tag); } } //////////////////////////////////////////////////////////////////////////////// // Implements feedback when adding special tags to a task. -void feedback_special_tags (const Task& task, const std::string& tag) -{ - if (Context::getContext ().verbose ("special")) - { +void feedback_special_tags(const Task& task, const std::string& tag) { + if (Context::getContext().verbose("special")) { std::string msg; - if (tag == "nocolor") msg = "The 'nocolor' special tag will disable color rules for this task."; - else if (tag == "nonag") msg = "The 'nonag' special tag will prevent nagging when this task is modified."; - else if (tag == "nocal") msg = "The 'nocal' special tag will keep this task off the 'calendar' report."; - else if (tag == "next") msg = "The 'next' special tag will boost the urgency of this task so it appears on the 'next' report."; + if (tag == "nocolor") + msg = "The 'nocolor' special tag will disable color rules for this task."; + else if (tag == "nonag") + msg = "The 'nonag' special tag will prevent nagging when this task is modified."; + else if (tag == "nocal") + msg = "The 'nocal' special tag will keep this task off the 'calendar' report."; + else if (tag == "next") + msg = + "The 'next' special tag will boost the urgency of this task so it appears on the 'next' " + "report."; - if (msg.length ()) - { - std::cout << format (msg, task.identifier ()) - << "\n"; + if (msg.length()) { + std::cout << format(msg, task.identifier()) << "\n"; } } } @@ -175,31 +139,20 @@ void feedback_special_tags (const Task& task, const std::string& tag) // // Implements: // Unblocked '' -void feedback_unblocked (const Task& task) -{ - if (Context::getContext ().verbose ("affected")) - { +void feedback_unblocked(const Task& task) { + if (Context::getContext().verbose("affected")) { // Get a list of tasks that depended on this task. - auto blocked = task.getBlockedTasks (); + auto blocked = task.getBlockedTasks(); // Scan all the tasks that were blocked by this task - for (auto& i : blocked) - { - auto blocking = i.getDependencyTasks (); - if (blocking.size () == 0) - { + for (auto& i : blocked) { + auto blocking = i.getDependencyTasks(); + if (blocking.size() == 0) { if (i.id) - std::cout << format ("Unblocked {1} '{2}'.", - i.id, - i.get ("description")) - << "\n"; - else - { - std::string uuid = i.get ("uuid"); - std::cout << format ("Unblocked {1} '{2}'.", - i.get ("uuid"), - i.get ("description")) - << "\n"; + std::cout << format("Unblocked {1} '{2}'.", i.id, i.get("description")) << "\n"; + else { + std::string uuid = i.get("uuid"); + std::cout << format("Unblocked {1} '{2}'.", i.get("uuid"), i.get("description")) << "\n"; } } } @@ -207,39 +160,35 @@ void feedback_unblocked (const Task& task) } /////////////////////////////////////////////////////////////////////////////// -void feedback_backlog () -{ +void feedback_backlog() { // If non-local sync is not set up, do not provide this feedback. - if (Context::getContext ().config.get ("sync.encryption_secret") == "") { + if (Context::getContext().config.get("sync.encryption_secret") == "") { return; } - if (Context::getContext ().verbose ("sync")) - { - int count = Context::getContext ().tdb2.num_local_changes (); + if (Context::getContext().verbose("sync")) { + int count = Context::getContext().tdb2.num_local_changes(); if (count) - Context::getContext ().footnote (format (count > 1 ? "There are {1} local changes. Sync required." - : "There is {1} local change. Sync required.", count)); + Context::getContext().footnote(format(count > 1 + ? "There are {1} local changes. Sync required." + : "There is {1} local change. Sync required.", + count)); } } /////////////////////////////////////////////////////////////////////////////// -std::string onProjectChange (Task& task, bool scope /* = true */) -{ +std::string onProjectChange(Task& task, bool scope /* = true */) { std::stringstream msg; - std::string project = task.get ("project"); + std::string project = task.get("project"); - if (project != "") - { - if (scope) - msg << format ("The project '{1}' has changed.", project) - << " "; + if (project != "") { + if (scope) msg << format("The project '{1}' has changed.", project) << " "; // Count pending and done tasks, for this project. int count_pending = 0; int count_done = 0; - std::vector all = Context::getContext ().tdb2.all_tasks (); - countTasks (all, project, count_pending, count_done); + std::vector all = Context::getContext().tdb2.all_tasks(); + countTasks(all, project, count_pending, count_done); // count_done count_pending percentage // ---------- ------------- ---------- @@ -255,72 +204,59 @@ std::string onProjectChange (Task& task, bool scope /* = true */) else percentage = (count_done * 100 / (count_done + count_pending)); - msg << format ("Project '{1}' is {2}% complete", project, percentage) - << ' '; + msg << format("Project '{1}' is {2}% complete", project, percentage) << ' '; if (count_pending == 1 && count_done == 0) - msg << format ("({1} task remaining).", count_pending); + msg << format("({1} task remaining).", count_pending); else - msg << format ("({1} of {2} tasks remaining).", count_pending, count_pending + count_done); + msg << format("({1} of {2} tasks remaining).", count_pending, count_pending + count_done); } - return msg.str (); + return msg.str(); } /////////////////////////////////////////////////////////////////////////////// -std::string onProjectChange (Task& task1, Task& task2) -{ - if (task1.get ("project") == task2.get ("project")) - return onProjectChange (task1, false); +std::string onProjectChange(Task& task1, Task& task2) { + if (task1.get("project") == task2.get("project")) return onProjectChange(task1, false); - std::string messages1 = onProjectChange (task1); - std::string messages2 = onProjectChange (task2); + std::string messages1 = onProjectChange(task1); + std::string messages2 = onProjectChange(task2); - if (messages1.length () && messages2.length ()) - return messages1 + '\n' + messages2; + if (messages1.length() && messages2.length()) return messages1 + '\n' + messages2; return messages1 + messages2; } /////////////////////////////////////////////////////////////////////////////// -std::string onExpiration (Task& task) -{ +std::string onExpiration(Task& task) { std::stringstream msg; - if (Context::getContext ().verbose ("affected")) - msg << format ("Task {1} '{2}' expired and was deleted.", - task.identifier (true), - task.get ("description")); + if (Context::getContext().verbose("affected")) + msg << format("Task {1} '{2}' expired and was deleted.", task.identifier(true), + task.get("description")); - return msg.str (); + return msg.str(); } /////////////////////////////////////////////////////////////////////////////// -static void countTasks ( - const std::vector & all, - const std::string& project, - int& count_pending, - int& count_done) -{ - for (auto& it : all) - { - if (it.get ("project") == project) - { - switch (it.getStatus ()) - { - case Task::pending: - case Task::waiting: - ++count_pending; - break; +static void countTasks(const std::vector& all, const std::string& project, int& count_pending, + int& count_done) { + for (auto& it : all) { + if (it.get("project") == project) { + switch (it.getStatus()) { + case Task::pending: + case Task::waiting: + ++count_pending; + break; - case Task::completed: - ++count_done; - break; + case Task::completed: + ++count_done; + break; - case Task::deleted: - case Task::recurring: - default: - break; + case Task::deleted: + case Task::recurring: + default: + break; } } } diff --git a/src/legacy.cpp b/src/legacy.cpp index 965e1d227..16b1f3292 100644 --- a/src/legacy.cpp +++ b/src/legacy.cpp @@ -27,16 +27,16 @@ #include // cmake.h include header must come first -#include -#include #include #include +#include +#include + #define STRING_LEGACY_PRIORITY "Legacy attribute found. Please change '{1}' to '{2}'." //////////////////////////////////////////////////////////////////////////////// -void legacyColumnMap (std::string& name) -{ +void legacyColumnMap(std::string& name) { // 2014-01-26: priority_long --> priority.long Mapping removed // 2014-01-26: entry_time --> entry Mapping removed // 2014-01-26: start_time --> start Mapping removed @@ -51,20 +51,18 @@ void legacyColumnMap (std::string& name) // 2014-01-26: description_only --> description.desc Mapping removed // One-time initialization, on demand. - static std::map legacyMap {{"priority.", "priority"}}; + static std::map legacyMap{{"priority.", "priority"}}; // If a legacy column was used, complain about it, but modify it anyway. - auto found = legacyMap.find (name); - if (found != legacyMap.end ()) - { - Context::getContext ().footnote (format (STRING_LEGACY_PRIORITY, name, found->second)); + auto found = legacyMap.find(name); + if (found != legacyMap.end()) { + Context::getContext().footnote(format(STRING_LEGACY_PRIORITY, name, found->second)); name = found->second; } } //////////////////////////////////////////////////////////////////////////////// -void legacySortColumnMap (std::string& name) -{ +void legacySortColumnMap(std::string& name) { // 2014-01-26: priority_long --> priority Mapping removed // 2014-01-26: entry_time --> entry Mapping removed // 2014-01-26: start_time --> start Mapping removed @@ -79,97 +77,83 @@ void legacySortColumnMap (std::string& name) // 2014-01-26: description_only --> description Mapping removed // One-time initialization, on demand. - static std::map legacyMap {{"priority.", "priority"}}; + static std::map legacyMap{{"priority.", "priority"}}; // If a legacy column was used, complain about it, but modify it anyway. - auto found = legacyMap.find (name); - if (found != legacyMap.end ()) - { - Context::getContext ().footnote (format (STRING_LEGACY_PRIORITY, name, found->second)); + auto found = legacyMap.find(name); + if (found != legacyMap.end()) { + Context::getContext().footnote(format(STRING_LEGACY_PRIORITY, name, found->second)); name = found->second; } } //////////////////////////////////////////////////////////////////////////////// -std::string legacyCheckForDeprecatedVariables () -{ - std::vector deprecated; - for (auto& it : Context::getContext ().config) - { +std::string legacyCheckForDeprecatedVariables() { + std::vector deprecated; + for (auto& it : Context::getContext().config) { // 2014-07-04: report.*.limit removed. // 2016-02-24: alias._query removed. // Deprecated in 2.5.0. // report.*.annotations - if (it.first.length () > 19 && - it.first.substr (0, 7) == "report." && - it.first.substr (it.first.length () - 12) == ".annotations") - deprecated.push_back (it.first); + if (it.first.length() > 19 && it.first.substr(0, 7) == "report." && + it.first.substr(it.first.length() - 12) == ".annotations") + deprecated.push_back(it.first); // Deprecated in 2.5.0. - if (it.first == "next" || - it.first == "annotations" || - it.first == "export.ical.class") - deprecated.push_back (it.first); + if (it.first == "next" || it.first == "annotations" || it.first == "export.ical.class") + deprecated.push_back(it.first); // Deprecated in 2.5.0. - if (it.first == "urgency.inherit.coefficient") - deprecated.push_back (it.first); + if (it.first == "urgency.inherit.coefficient") deprecated.push_back(it.first); } std::stringstream out; - if (deprecated.size ()) - { + if (deprecated.size()) { out << "Your .taskrc file contains variables that are deprecated:\n"; - for (const auto& dep : deprecated) - out << " " << dep << "\n"; + for (const auto& dep : deprecated) out << " " << dep << "\n"; out << "\n"; } - return out.str (); + return out.str(); } //////////////////////////////////////////////////////////////////////////////// -std::string legacyCheckForDeprecatedColumns () -{ - std::vector deprecated; - for (auto& it : Context::getContext ().config) - { - if (it.first.find ("report") == 0) - { +std::string legacyCheckForDeprecatedColumns() { + std::vector deprecated; + for (auto& it : Context::getContext().config) { + if (it.first.find("report") == 0) { // Deprecated in 2.0.0 - std::string value = Context::getContext ().config.get (it.first); - if (value.find ("entry_time") != std::string::npos || - value.find ("start_time") != std::string::npos || - value.find ("end_time") != std::string::npos) - deprecated.push_back (it.first); + std::string value = Context::getContext().config.get(it.first); + if (value.find("entry_time") != std::string::npos || + value.find("start_time") != std::string::npos || + value.find("end_time") != std::string::npos) + deprecated.push_back(it.first); } } std::stringstream out; out << "\n"; - if (deprecated.size ()) - { - out << "Your .taskrc file contains reports with deprecated columns. Please check for entry_time, start_time or end_time in:\n"; + if (deprecated.size()) { + out << "Your .taskrc file contains reports with deprecated columns. Please check for " + "entry_time, start_time or end_time in:\n"; for (const auto& dep : deprecated) - out << " " << dep << "=" << Context::getContext ().config.get (dep) << "\n"; + out << " " << dep << "=" << Context::getContext().config.get(dep) << "\n"; out << "\n"; } - return out.str (); + return out.str(); } //////////////////////////////////////////////////////////////////////////////// -void legacyAttributeMap (std::string& name) -{ +void legacyAttributeMap(std::string& name) { // TW-1274, 2.4.0 - if (name == "modification") - name = "modified"; + if (name == "modification") name = "modified"; } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/lex.cpp b/src/lex.cpp index 366962bc7..6e675eef5 100644 --- a/src/lex.cpp +++ b/src/lex.cpp @@ -1,22 +1,21 @@ //////////////////////////////////////////////////////////////////////////////// -#include -#include #include +#include + +#include Context context; -int main (int argc, char** argv) -{ - for (auto i = 1; i < argc; i++) - { +int main(int argc, char** argv) { + for (auto i = 1; i < argc; i++) { std::cout << "argument '" << argv[i] << "'\n"; - Lexer l (argv[i]); + Lexer l(argv[i]); std::string token; Lexer::Type type; - while (l.token (token, type)) - std::cout << " token '" << token << "' " << Lexer::typeToString (type) << "\n"; + while (l.token(token, type)) + std::cout << " token '" << token << "' " << Lexer::typeToString(type) << "\n"; } } diff --git a/src/main.cpp b/src/main.cpp index d360876d0..f64daeee7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -27,53 +27,44 @@ #include // cmake.h include header must come first +#include + +#include #include #include -#include -#include #include //////////////////////////////////////////////////////////////////////////////// -int main (int argc, const char** argv) -{ - int status {0}; +int main(int argc, const char** argv) { + int status{0}; Context globalContext; - Context::setContext (&globalContext); + Context::setContext(&globalContext); // Lightweight version checking that doesn't require initialization or any I/O. - if (argc == 2 && !strcmp (argv[1], "--version")) - { + if (argc == 2 && !strcmp(argv[1], "--version")) { std::cout << VERSION << "\n"; - } - else - { - try - { - status = Context::getContext ().initialize (argc, argv); - if (status == 0) - status = Context::getContext ().run (); + } else { + try { + status = Context::getContext().initialize(argc, argv); + if (status == 0) status = Context::getContext().run(); } - catch (const std::string& error) - { + catch (const std::string& error) { std::cerr << error << "\n"; status = -1; } - catch (std::bad_alloc& error) - { - std::cerr << "Error: Memory allocation failed: " << error.what () << "\n"; + catch (std::bad_alloc& error) { + std::cerr << "Error: Memory allocation failed: " << error.what() << "\n"; status = -3; } - catch (const std::regex_error& e) - { + catch (const std::regex_error& e) { std::cout << "regex_error caught: " << e.what() << '\n'; } - catch (...) - { + catch (...) { std::cerr << "Unknown error. Please report.\n"; status = -2; } diff --git a/src/main.h b/src/main.h index 3b29a74f1..9d15a09fa 100644 --- a/src/main.h +++ b/src/main.h @@ -27,66 +27,69 @@ #ifndef INCLUDED_MAIN #define INCLUDED_MAIN -#include -#include -#include -#include -#include -#include +#include #include #include -#include +#include + +#include +#include +#include +#include +#include // recur.cpp -void handleRecurrence (); -void handleUntil (); -Datetime getNextRecurrence (Datetime&, std::string&); -bool generateDueDates (Task&, std::vector &); -void updateRecurrenceMask (Task&); +void handleRecurrence(); +void handleUntil(); +Datetime getNextRecurrence(Datetime&, std::string&); +bool generateDueDates(Task&, std::vector&); +void updateRecurrenceMask(Task&); // recur2.cpp -void handleRecurrence2 (); +void handleRecurrence2(); // nag.cpp -void nag (std::vector &); +void nag(std::vector&); // rules.cpp -void initializeColorRules (); -void autoColorize (Task&, Color&); -std::string colorizeHeader (const std::string&); -std::string colorizeFootnote (const std::string&); -std::string colorizeError (const std::string&); -std::string colorizeDebug (const std::string&); +void initializeColorRules(); +void autoColorize(Task&, Color&); +std::string colorizeHeader(const std::string&); +std::string colorizeFootnote(const std::string&); +std::string colorizeError(const std::string&); +std::string colorizeDebug(const std::string&); // dependency.cpp -bool dependencyIsCircular (const Task&); -void dependencyChainOnComplete (Task&); -void dependencyChainOnStart (Task&); +bool dependencyIsCircular(const Task&); +void dependencyChainOnComplete(Task&); +void dependencyChainOnStart(Task&); // feedback.cpp -std::string renderAttribute (const std::string&, const std::string&, const std::string& format = ""); -void feedback_affected (const std::string&); -void feedback_affected (const std::string&, int); -void feedback_affected (const std::string&, const Task&); -void feedback_reserved_tags (const std::string&); -void feedback_special_tags (const Task&, const std::string&); -void feedback_unblocked (const Task&); -void feedback_backlog (); -std::string onProjectChange (Task&, bool scope = true); -std::string onProjectChange (Task&, Task&); -std::string onExpiration (Task&); +std::string renderAttribute(const std::string&, const std::string&, const std::string& format = ""); +void feedback_affected(const std::string&); +void feedback_affected(const std::string&, int); +void feedback_affected(const std::string&, const Task&); +void feedback_reserved_tags(const std::string&); +void feedback_special_tags(const Task&, const std::string&); +void feedback_unblocked(const Task&); +void feedback_backlog(); +std::string onProjectChange(Task&, bool scope = true); +std::string onProjectChange(Task&, Task&); +std::string onExpiration(Task&); // sort.cpp -void sort_tasks (std::vector &, std::vector &, const std::string&); -void sort_projects (std::list >& sorted, std::map & allProjects); -void sort_projects (std::list >& sorted, std::map & allProjects); +void sort_tasks(std::vector&, std::vector&, const std::string&); +void sort_projects(std::list>& sorted, + std::map& allProjects); +void sort_projects(std::list>& sorted, + std::map& allProjects); // legacy.cpp -void legacyColumnMap (std::string&); -void legacySortColumnMap (std::string&); -std::string legacyCheckForDeprecatedVariables (); -std::string legacyCheckForDeprecatedColumns (); -void legacyAttributeMap (std::string&); +void legacyColumnMap(std::string&); +void legacySortColumnMap(std::string&); +std::string legacyCheckForDeprecatedVariables(); +std::string legacyCheckForDeprecatedColumns(); +void legacyAttributeMap(std::string&); #endif //////////////////////////////////////////////////////////////////////////////// diff --git a/src/nag.cpp b/src/nag.cpp index 55085a8b2..057567582 100644 --- a/src/nag.cpp +++ b/src/nag.cpp @@ -24,11 +24,13 @@ // //////////////////////////////////////////////////////////////////////////////// -#include #include + +#include // cmake.h include header must come first #include + #include #include #include @@ -36,23 +38,17 @@ //////////////////////////////////////////////////////////////////////////////// // Generates a nag message when there are READY tasks of a higher urgency. -void nag (std::vector & tasks) -{ - auto msg = Context::getContext ().config.get ("nag"); - if (msg == "") - return; +void nag(std::vector& tasks) { + auto msg = Context::getContext().config.get("nag"); + if (msg == "") return; - auto pending = Context::getContext ().tdb2.pending_tasks (); + auto pending = Context::getContext().tdb2.pending_tasks(); for (auto& t1 : tasks) { - if (t1.hasTag ("nonag")) - continue; + if (t1.hasTag("nonag")) continue; for (auto& t2 : pending) { - if (t1.get ("uuid") != t2.get ("uuid") && - t2.hasTag ("READY") && - t1.urgency () < t2.urgency ()) - { - Context::getContext ().footnote (msg); + if (t1.get("uuid") != t2.get("uuid") && t2.hasTag("READY") && t1.urgency() < t2.urgency()) { + Context::getContext().footnote(msg); return; } } diff --git a/src/recur.cpp b/src/recur.cpp index 463534ecf..f5c9f3979 100644 --- a/src/recur.cpp +++ b/src/recur.cpp @@ -27,109 +27,100 @@ #include // cmake.h include header must come first -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include #include #include +#include #include -#include -#include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include //////////////////////////////////////////////////////////////////////////////// // Scans all tasks, and for any recurring tasks, determines whether any new // child tasks need to be generated to fill gaps. -void handleRecurrence () -{ +void handleRecurrence() { // Recurrence can be disabled. // Note: This is currently a workaround for TD-44, TW-1520. - if (! Context::getContext ().config.getBoolean ("recurrence")) - return; + if (!Context::getContext().config.getBoolean("recurrence")) return; - auto tasks = Context::getContext ().tdb2.pending_tasks (); + auto tasks = Context::getContext().tdb2.pending_tasks(); Datetime now; // Look at all tasks and find any recurring ones. - for (auto& t : tasks) - { - if (t.getStatus () == Task::recurring) - { + for (auto& t : tasks) { + if (t.getStatus() == Task::recurring) { // Generate a list of due dates for this recurring task, regardless of // the mask. - std::vector due; - if (! generateDueDates (t, due)) - { + std::vector due; + if (!generateDueDates(t, due)) { // Determine the end date. - t.setStatus (Task::deleted); - Context::getContext ().tdb2.modify (t); - Context::getContext ().footnote (onExpiration (t)); + t.setStatus(Task::deleted); + Context::getContext().tdb2.modify(t); + Context::getContext().footnote(onExpiration(t)); continue; } // Get the mask from the parent task. - auto mask = t.get ("mask"); + auto mask = t.get("mask"); // Iterate over the due dates, and check each against the mask. auto changed = false; unsigned int i = 0; - for (auto& d : due) - { - if (mask.length () <= i) - { + for (auto& d : due) { + if (mask.length() <= i) { changed = true; - Task rec (t); // Clone the parent. - rec.setStatus (Task::pending); // Change the status. - rec.set ("uuid", uuid ()); // New UUID. - rec.set ("parent", t.get ("uuid")); // Remember mom. - rec.setAsNow ("entry"); // New entry date. - rec.set ("due", format (d.toEpoch ())); + Task rec(t); // Clone the parent. + rec.setStatus(Task::pending); // Change the status. + rec.set("uuid", uuid()); // New UUID. + rec.set("parent", t.get("uuid")); // Remember mom. + rec.setAsNow("entry"); // New entry date. + rec.set("due", format(d.toEpoch())); - if (t.has ("wait")) - { - Datetime old_wait (t.get_date ("wait")); - Datetime old_due (t.get_date ("due")); - Datetime due (d); - rec.set ("wait", format ((due + (old_wait - old_due)).toEpoch ())); - rec.setStatus (Task::waiting); + if (t.has("wait")) { + Datetime old_wait(t.get_date("wait")); + Datetime old_due(t.get_date("due")); + Datetime due(d); + rec.set("wait", format((due + (old_wait - old_due)).toEpoch())); + rec.setStatus(Task::waiting); mask += 'W'; - } - else - { + } else { mask += '-'; - rec.setStatus (Task::pending); + rec.setStatus(Task::pending); } - rec.set ("imask", i); - rec.remove ("mask"); // Remove the mask of the parent. + rec.set("imask", i); + rec.remove("mask"); // Remove the mask of the parent. // Add the new task to the DB. - Context::getContext ().tdb2.add (rec); + Context::getContext().tdb2.add(rec); } ++i; } // Only modify the parent if necessary. - if (changed) - { - t.set ("mask", mask); - Context::getContext ().tdb2.modify (t); + if (changed) { + t.set("mask", mask); + Context::getContext().tdb2.modify(t); - if (Context::getContext ().verbose ("recur")) - Context::getContext ().footnote (format ("Creating recurring task instance '{1}'", t.get ("description"))); + if (Context::getContext().verbose("recur")) + Context::getContext().footnote( + format("Creating recurring task instance '{1}'", t.get("description"))); } } } @@ -140,292 +131,242 @@ void handleRecurrence () // period (recur). Then generate a set of corresponding dates. // // Returns false if the parent recurring task is depleted. -bool generateDueDates (Task& parent, std::vector & allDue) -{ +bool generateDueDates(Task& parent, std::vector& allDue) { // Determine due date, recur period and until date. - Datetime due (parent.get_date ("due")); - if (due._date == 0) - return false; + Datetime due(parent.get_date("due")); + if (due._date == 0) return false; - std::string recur = parent.get ("recur"); + std::string recur = parent.get("recur"); bool specificEnd = false; Datetime until; - if (parent.get ("until") != "") - { - until = Datetime (parent.get ("until")); + if (parent.get("until") != "") { + until = Datetime(parent.get("until")); specificEnd = true; } - auto recurrence_limit = Context::getContext ().config.getInteger ("recurrence.limit"); + auto recurrence_limit = Context::getContext().config.getInteger("recurrence.limit"); int recurrence_counter = 0; Datetime now; - for (Datetime i = due; ; i = getNextRecurrence (i, recur)) - { - allDue.push_back (i); + for (Datetime i = due;; i = getNextRecurrence(i, recur)) { + allDue.push_back(i); - if (specificEnd && i > until) - { + if (specificEnd && i > until) { // If i > until, it means there are no more tasks to generate, and if the // parent mask contains all + or X, then there never will be another task // to generate, and this parent task may be safely reaped. - auto mask = parent.get ("mask"); - if (mask.length () == allDue.size () && - mask.find ('-') == std::string::npos) - return false; + auto mask = parent.get("mask"); + if (mask.length() == allDue.size() && mask.find('-') == std::string::npos) return false; return true; } - if (i > now) - ++recurrence_counter; + if (i > now) ++recurrence_counter; - if (recurrence_counter >= recurrence_limit) - return true; + if (recurrence_counter >= recurrence_limit) return true; } return true; } //////////////////////////////////////////////////////////////////////////////// -Datetime getNextRecurrence (Datetime& current, std::string& period) -{ - auto m = current.month (); - auto d = current.day (); - auto y = current.year (); - auto ho = current.hour (); - auto mi = current.minute (); - auto se = current.second (); +Datetime getNextRecurrence(Datetime& current, std::string& period) { + auto m = current.month(); + auto d = current.day(); + auto y = current.year(); + auto ho = current.hour(); + auto mi = current.minute(); + auto se = current.second(); // Some periods are difficult, because they can be vague. - if (period == "monthly" || - period == "P1M") - { - if (++m > 12) - { - m -= 12; - ++y; + if (period == "monthly" || period == "P1M") { + if (++m > 12) { + m -= 12; + ++y; } - while (! Datetime::valid (y, m, d)) - --d; + while (!Datetime::valid(y, m, d)) --d; - return Datetime (y, m, d, ho, mi, se); + return Datetime(y, m, d, ho, mi, se); } - else if (period == "weekdays") - { - auto dow = current.dayOfWeek (); + else if (period == "weekdays") { + auto dow = current.dayOfWeek(); int days; - if (dow == 5) days = 3; - else if (dow == 6) days = 2; - else days = 1; + if (dow == 5) + days = 3; + else if (dow == 6) + days = 2; + else + days = 1; return current + (days * 86400); } - else if (unicodeLatinDigit (period[0]) && - period[period.length () - 1] == 'm') - { - int increment = strtol (period.substr (0, period.length () - 1).c_str (), nullptr, 10); + else if (unicodeLatinDigit(period[0]) && period[period.length() - 1] == 'm') { + int increment = strtol(period.substr(0, period.length() - 1).c_str(), nullptr, 10); if (increment <= 0) - throw format ("Recurrence period '{1}' is equivalent to {2} and hence invalid.", period, increment); + throw format("Recurrence period '{1}' is equivalent to {2} and hence invalid.", period, + increment); m += increment; - while (m > 12) - { - m -= 12; - ++y; + while (m > 12) { + m -= 12; + ++y; } - while (! Datetime::valid (y, m, d)) - --d; + while (!Datetime::valid(y, m, d)) --d; - return Datetime (y, m, d, ho, mi, se); + return Datetime(y, m, d, ho, mi, se); } - else if (period[0] == 'P' && - Lexer::isAllDigits (period.substr (1, period.length () - 2)) && - period[period.length () - 1] == 'M') - { - int increment = strtol (period.substr (1, period.length () - 2).c_str (), nullptr, 10); + else if (period[0] == 'P' && Lexer::isAllDigits(period.substr(1, period.length() - 2)) && + period[period.length() - 1] == 'M') { + int increment = strtol(period.substr(1, period.length() - 2).c_str(), nullptr, 10); if (increment <= 0) - throw format ("Recurrence period '{1}' is equivalent to {2} and hence invalid.", period, increment); + throw format("Recurrence period '{1}' is equivalent to {2} and hence invalid.", period, + increment); m += increment; - while (m > 12) - { - m -= 12; - ++y; + while (m > 12) { + m -= 12; + ++y; } - while (! Datetime::valid (y, m, d)) - --d; + while (!Datetime::valid(y, m, d)) --d; - return Datetime (y, m, d); + return Datetime(y, m, d); } - else if (period == "quarterly" || - period == "P3M") - { + else if (period == "quarterly" || period == "P3M") { m += 3; - if (m > 12) - { - m -= 12; - ++y; + if (m > 12) { + m -= 12; + ++y; } - while (! Datetime::valid (y, m, d)) - --d; + while (!Datetime::valid(y, m, d)) --d; - return Datetime (y, m, d, ho, mi, se); + return Datetime(y, m, d, ho, mi, se); } - else if (unicodeLatinDigit (period[0]) && period[period.length () - 1] == 'q') - { - int increment = strtol (period.substr (0, period.length () - 1).c_str (), nullptr, 10); + else if (unicodeLatinDigit(period[0]) && period[period.length() - 1] == 'q') { + int increment = strtol(period.substr(0, period.length() - 1).c_str(), nullptr, 10); if (increment <= 0) - throw format ("Recurrence period '{1}' is equivalent to {2} and hence invalid.", period, increment); + throw format("Recurrence period '{1}' is equivalent to {2} and hence invalid.", period, + increment); m += 3 * increment; - while (m > 12) - { - m -= 12; - ++y; + while (m > 12) { + m -= 12; + ++y; } - while (! Datetime::valid (y, m, d)) - --d; + while (!Datetime::valid(y, m, d)) --d; - return Datetime (y, m, d, ho, mi, se); + return Datetime(y, m, d, ho, mi, se); } - else if (period == "semiannual" || - period == "P6M") - { + else if (period == "semiannual" || period == "P6M") { m += 6; - if (m > 12) - { - m -= 12; - ++y; + if (m > 12) { + m -= 12; + ++y; } - while (! Datetime::valid (y, m, d)) - --d; + while (!Datetime::valid(y, m, d)) --d; - return Datetime (y, m, d, ho, mi, se); + return Datetime(y, m, d, ho, mi, se); } - else if (period == "bimonthly" || - period == "P2M") - { + else if (period == "bimonthly" || period == "P2M") { m += 2; - if (m > 12) - { - m -= 12; - ++y; + if (m > 12) { + m -= 12; + ++y; } - while (! Datetime::valid (y, m, d)) - --d; + while (!Datetime::valid(y, m, d)) --d; - return Datetime (y, m, d, ho, mi, se); + return Datetime(y, m, d, ho, mi, se); } - else if (period == "biannual" || - period == "biyearly" || - period == "P2Y") - { + else if (period == "biannual" || period == "biyearly" || period == "P2Y") { y += 2; - return Datetime (y, m, d, ho, mi, se); + return Datetime(y, m, d, ho, mi, se); } - else if (period == "annual" || - period == "yearly" || - period == "P1Y") - { + else if (period == "annual" || period == "yearly" || period == "P1Y") { y += 1; // If the due data just happens to be 2/29 in a leap year, then simply // incrementing y is going to create an invalid date. - if (m == 2 && d == 29) - d = 28; + if (m == 2 && d == 29) d = 28; - return Datetime (y, m, d, ho, mi, se); + return Datetime(y, m, d, ho, mi, se); } // Add the period to current, and we're done. std::string::size_type idx = 0; Duration p; - if (! p.parse (period, idx)) - throw std::string (format ("The recurrence value '{1}' is not valid.", period)); + if (!p.parse(period, idx)) + throw std::string(format("The recurrence value '{1}' is not valid.", period)); - return current + p.toTime_t (); + return current + p.toTime_t(); } //////////////////////////////////////////////////////////////////////////////// // When the status of a recurring child task changes, the parent task must // update it's mask. -void updateRecurrenceMask (Task& task) -{ - auto uuid = task.get ("parent"); +void updateRecurrenceMask(Task& task) { + auto uuid = task.get("parent"); Task parent; - if (uuid != "" && - Context::getContext ().tdb2.get (uuid, parent)) - { - unsigned int index = strtol (task.get ("imask").c_str (), nullptr, 10); - auto mask = parent.get ("mask"); - if (mask.length () > index) - { - mask[index] = (task.getStatus () == Task::pending) ? '-' - : (task.getStatus () == Task::completed) ? '+' - : (task.getStatus () == Task::deleted) ? 'X' - : (task.getStatus () == Task::waiting) ? 'W' - : '?'; - } - else - { + if (uuid != "" && Context::getContext().tdb2.get(uuid, parent)) { + unsigned int index = strtol(task.get("imask").c_str(), nullptr, 10); + auto mask = parent.get("mask"); + if (mask.length() > index) { + mask[index] = (task.getStatus() == Task::pending) ? '-' + : (task.getStatus() == Task::completed) ? '+' + : (task.getStatus() == Task::deleted) ? 'X' + : (task.getStatus() == Task::waiting) ? 'W' + : '?'; + } else { std::string mask; - for (unsigned int i = 0; i < index; ++i) - mask += "?"; + for (unsigned int i = 0; i < index; ++i) mask += "?"; - mask += (task.getStatus () == Task::pending) ? '-' - : (task.getStatus () == Task::completed) ? '+' - : (task.getStatus () == Task::deleted) ? 'X' - : (task.getStatus () == Task::waiting) ? 'W' - : '?'; + mask += (task.getStatus() == Task::pending) ? '-' + : (task.getStatus() == Task::completed) ? '+' + : (task.getStatus() == Task::deleted) ? 'X' + : (task.getStatus() == Task::waiting) ? 'W' + : '?'; } - parent.set ("mask", mask); - Context::getContext ().tdb2.modify (parent); + parent.set("mask", mask); + Context::getContext().tdb2.modify(parent); } } //////////////////////////////////////////////////////////////////////////////// // Delete expired tasks. -void handleUntil () -{ +void handleUntil() { Datetime now; - auto tasks = Context::getContext ().tdb2.pending_tasks (); - for (auto& t : tasks) - { + auto tasks = Context::getContext().tdb2.pending_tasks(); + for (auto& t : tasks) { // TODO What about expiring template tasks? - if (t.getStatus () == Task::pending && - t.has ("until")) - { - auto until = Datetime (t.get_date ("until")); - if (until < now) - { - Context::getContext ().debug (format ("handleUntil: recurrence expired until {1} < now {2}", until.toISOLocalExtended (), now.toISOLocalExtended ())); - t.setStatus (Task::deleted); - Context::getContext ().tdb2.modify(t); - Context::getContext ().footnote (onExpiration (t)); + if (t.getStatus() == Task::pending && t.has("until")) { + auto until = Datetime(t.get_date("until")); + if (until < now) { + Context::getContext().debug(format("handleUntil: recurrence expired until {1} < now {2}", + until.toISOLocalExtended(), now.toISOLocalExtended())); + t.setStatus(Task::deleted); + Context::getContext().tdb2.modify(t); + Context::getContext().footnote(onExpiration(t)); } } } diff --git a/src/rules.cpp b/src/rules.cpp index 4edf81d5f..924644233 100644 --- a/src/rules.cpp +++ b/src/rules.cpp @@ -27,175 +27,145 @@ #include // cmake.h include header must come first -#include #include #include -#include #include +#include +#include -static std::map gsColor; -static std::vector gsPrecedence; +static std::map gsColor; +static std::vector gsPrecedence; static Datetime now; //////////////////////////////////////////////////////////////////////////////// -void initializeColorRules () -{ +void initializeColorRules() { // If color is not enable/supported, short circuit. - if (! Context::getContext ().color ()) - return; + if (!Context::getContext().color()) return; - try - { - gsColor.clear (); - gsPrecedence.clear (); + try { + gsColor.clear(); + gsPrecedence.clear(); // Load all the configuration values, filter to only the ones that begin with // "color.", then store name/value in gsColor, and name in rules. - std::vector rules; - for (const auto& v : Context::getContext ().config) - { - if (! v.first.compare (0, 6, "color.", 6)) - { - Color c (v.second); + std::vector rules; + for (const auto& v : Context::getContext().config) { + if (!v.first.compare(0, 6, "color.", 6)) { + Color c(v.second); gsColor[v.first] = c; - rules.push_back (v.first); + rules.push_back(v.first); } } // Load the rule.precedence.color list, split it, then autocomplete against // the 'rules' vector loaded above. - std::vector results; - auto precedence = split (Context::getContext ().config.get ("rule.precedence.color"), ','); + std::vector results; + auto precedence = split(Context::getContext().config.get("rule.precedence.color"), ','); - for (const auto& p : precedence) - { + for (const auto& p : precedence) { // Add the leading "color." string. std::string rule = "color." + p; - autoComplete (rule, rules, results, 3); // Hard-coded 3. + autoComplete(rule, rules, results, 3); // Hard-coded 3. - for (auto& r : results) - gsPrecedence.push_back (r); + for (auto& r : results) gsPrecedence.push_back(r); } } - catch (const std::string& e) - { - Context::getContext ().error (e); + catch (const std::string& e) { + Context::getContext().error(e); } } //////////////////////////////////////////////////////////////////////////////// -static void applyColor (const Color& base, Color& c, bool merge) -{ +static void applyColor(const Color& base, Color& c, bool merge) { if (merge) - c.blend (base); + c.blend(base); else c = base; } //////////////////////////////////////////////////////////////////////////////// -static void colorizeBlocked (Task& task, const Color& base, Color& c, bool merge) -{ - if (task.is_blocked) - applyColor (base, c, merge); +static void colorizeBlocked(Task& task, const Color& base, Color& c, bool merge) { + if (task.is_blocked) applyColor(base, c, merge); } //////////////////////////////////////////////////////////////////////////////// -static void colorizeBlocking (Task& task, const Color& base, Color& c, bool merge) -{ - if (task.is_blocking) - applyColor (base, c, merge); +static void colorizeBlocking(Task& task, const Color& base, Color& c, bool merge) { + if (task.is_blocking) applyColor(base, c, merge); } //////////////////////////////////////////////////////////////////////////////// -static void colorizeTagged (Task& task, const Color& base, Color& c, bool merge) -{ - if (task.getTagCount ()) - applyColor (base, c, merge); +static void colorizeTagged(Task& task, const Color& base, Color& c, bool merge) { + if (task.getTagCount()) applyColor(base, c, merge); } //////////////////////////////////////////////////////////////////////////////// -static void colorizeActive (Task& task, const Color& base, Color& c, bool merge) -{ +static void colorizeActive(Task& task, const Color& base, Color& c, bool merge) { // TODO: Not consistent with the implementation of the +ACTIVE virtual tag - if (task.has ("start") && - !task.has ("end")) - applyColor (base, c, merge); + if (task.has("start") && !task.has("end")) applyColor(base, c, merge); } //////////////////////////////////////////////////////////////////////////////// -static void colorizeScheduled (Task& task, const Color& base, Color& c, bool merge) -{ +static void colorizeScheduled(Task& task, const Color& base, Color& c, bool merge) { // TODO: Not consistent with the implementation of the +SCHEDULED virtual tag - if (task.has ("scheduled") && - Datetime (task.get_date ("scheduled")) <= now) - applyColor (base, c, merge); + if (task.has("scheduled") && Datetime(task.get_date("scheduled")) <= now) + applyColor(base, c, merge); } //////////////////////////////////////////////////////////////////////////////// -static void colorizeUntil (Task& task, const Color& base, Color& c, bool merge) -{ - if (task.has ("until")) - applyColor (base, c, merge); +static void colorizeUntil(Task& task, const Color& base, Color& c, bool merge) { + if (task.has("until")) applyColor(base, c, merge); } //////////////////////////////////////////////////////////////////////////////// -static void colorizeTag (Task& task, const std::string& rule, const Color& base, Color& c, bool merge) -{ - if (task.hasTag (rule.substr (10))) - applyColor (base, c, merge); +static void colorizeTag(Task& task, const std::string& rule, const Color& base, Color& c, + bool merge) { + if (task.hasTag(rule.substr(10))) applyColor(base, c, merge); } //////////////////////////////////////////////////////////////////////////////// -static void colorizeProject (Task& task, const std::string& rule, const Color& base, Color& c, bool merge) -{ +static void colorizeProject(Task& task, const std::string& rule, const Color& base, Color& c, + bool merge) { // Observe the case sensitivity setting. - bool sensitive = Context::getContext ().config.getBoolean ("search.case.sensitive"); + bool sensitive = Context::getContext().config.getBoolean("search.case.sensitive"); - auto project = task.get ("project"); - auto rule_trunc = rule.substr (14); + auto project = task.get("project"); + auto rule_trunc = rule.substr(14); // Match project names leftmost. - if (rule_trunc.length () <= project.length ()) - if (compare (rule_trunc, project.substr (0, rule_trunc.length ()), sensitive)) - applyColor (base, c, merge); + if (rule_trunc.length() <= project.length()) + if (compare(rule_trunc, project.substr(0, rule_trunc.length()), sensitive)) + applyColor(base, c, merge); } //////////////////////////////////////////////////////////////////////////////// -static void colorizeProjectNone (Task& task, const Color& base, Color& c, bool merge) -{ - if(!task.has ("project")) - applyColor (base, c, merge); +static void colorizeProjectNone(Task& task, const Color& base, Color& c, bool merge) { + if (!task.has("project")) applyColor(base, c, merge); } //////////////////////////////////////////////////////////////////////////////// -static void colorizeTagNone (Task& task, const Color& base, Color& c, bool merge) -{ - if (task.getTagCount () == 0) - applyColor (base, c, merge); +static void colorizeTagNone(Task& task, const Color& base, Color& c, bool merge) { + if (task.getTagCount() == 0) applyColor(base, c, merge); } //////////////////////////////////////////////////////////////////////////////// -static void colorizeKeyword (Task& task, const std::string& rule, const Color& base, Color& c, bool merge) -{ +static void colorizeKeyword(Task& task, const std::string& rule, const Color& base, Color& c, + bool merge) { // Observe the case sensitivity setting. - auto sensitive = Context::getContext ().config.getBoolean ("search.case.sensitive"); + auto sensitive = Context::getContext().config.getBoolean("search.case.sensitive"); // The easiest thing to check is the description, because it is just one // attribute. - if (find (task.get ("description"), rule.substr (14), sensitive) != std::string::npos) - applyColor (base, c, merge); + if (find(task.get("description"), rule.substr(14), sensitive) != std::string::npos) + applyColor(base, c, merge); // Failing the description check, look at all annotations, returning on the // first match. - else - { - for (const auto& att : task.getAnnotations ()) - { - if (find (att.second, rule.substr (14), sensitive) != std::string::npos) - { - applyColor (base, c, merge); + else { + for (const auto& att : task.getAnnotations()) { + if (find(att.second, rule.substr(14), sensitive) != std::string::npos) { + applyColor(base, c, merge); return; } } @@ -203,146 +173,132 @@ static void colorizeKeyword (Task& task, const std::string& rule, const Color& b } //////////////////////////////////////////////////////////////////////////////// -static void colorizeUDA (Task& task, const std::string& rule, const Color& base, Color& c, bool merge) -{ +static void colorizeUDA(Task& task, const std::string& rule, const Color& base, Color& c, + bool merge) { // Is the rule color.uda.name.value or color.uda.name? - auto pos = rule.find ('.', 10); - if (pos == std::string::npos) - { - if (task.has (rule.substr (10))) - applyColor (base, c, merge); - } - else - { - auto uda = rule.substr (10, pos - 10); - auto val = rule.substr (pos + 1); - if ((val == "none" && ! task.has (uda)) || - task.get (uda) == val) - applyColor (base, c, merge); + auto pos = rule.find('.', 10); + if (pos == std::string::npos) { + if (task.has(rule.substr(10))) applyColor(base, c, merge); + } else { + auto uda = rule.substr(10, pos - 10); + auto val = rule.substr(pos + 1); + if ((val == "none" && !task.has(uda)) || task.get(uda) == val) applyColor(base, c, merge); } } //////////////////////////////////////////////////////////////////////////////// -static void colorizeDue (Task& task, const Color& base, Color& c, bool merge) -{ - if (task.is_due ()) - applyColor (base, c, merge); +static void colorizeDue(Task& task, const Color& base, Color& c, bool merge) { + if (task.is_due()) applyColor(base, c, merge); } //////////////////////////////////////////////////////////////////////////////// -static void colorizeDueToday (Task& task, const Color& base, Color& c, bool merge) -{ - if (task.is_duetoday ()) - applyColor (base, c, merge); +static void colorizeDueToday(Task& task, const Color& base, Color& c, bool merge) { + if (task.is_duetoday()) applyColor(base, c, merge); } //////////////////////////////////////////////////////////////////////////////// -static void colorizeOverdue (Task& task, const Color& base, Color& c, bool merge) -{ - if (task.is_overdue ()) - applyColor (base, c, merge); +static void colorizeOverdue(Task& task, const Color& base, Color& c, bool merge) { + if (task.is_overdue()) applyColor(base, c, merge); } //////////////////////////////////////////////////////////////////////////////// -static void colorizeRecurring (Task& task, const Color& base, Color& c, bool merge) -{ - if (task.has ("recur")) - applyColor (base, c, merge); +static void colorizeRecurring(Task& task, const Color& base, Color& c, bool merge) { + if (task.has("recur")) applyColor(base, c, merge); } //////////////////////////////////////////////////////////////////////////////// -static void colorizeCompleted (Task& task, const Color& base, Color& c, bool merge) -{ - if (task.getStatus () == Task::completed) - applyColor (base, c, merge); +static void colorizeCompleted(Task& task, const Color& base, Color& c, bool merge) { + if (task.getStatus() == Task::completed) applyColor(base, c, merge); } //////////////////////////////////////////////////////////////////////////////// -static void colorizeDeleted (Task& task, const Color& base, Color& c, bool merge) -{ - if (task.getStatus () == Task::deleted) - applyColor (base, c, merge); +static void colorizeDeleted(Task& task, const Color& base, Color& c, bool merge) { + if (task.getStatus() == Task::deleted) applyColor(base, c, merge); } //////////////////////////////////////////////////////////////////////////////// -void autoColorize (Task& task, Color& c) -{ +void autoColorize(Task& task, Color& c) { // The special tag 'nocolor' overrides all auto and specific colorization. - if (! Context::getContext ().color () || - task.hasTag ("nocolor")) - { - c = Color (); + if (!Context::getContext().color() || task.hasTag("nocolor")) { + c = Color(); return; } - auto merge = Context::getContext ().config.getBoolean ("rule.color.merge"); + auto merge = Context::getContext().config.getBoolean("rule.color.merge"); // Note: c already contains colors specifically assigned via command. // Note: These rules form a hierarchy - the last rule is King, hence the // reverse iterator. - for (auto r = gsPrecedence.rbegin (); r != gsPrecedence.rend (); ++r) - { + for (auto r = gsPrecedence.rbegin(); r != gsPrecedence.rend(); ++r) { Color base = gsColor[*r]; - if (base.nontrivial ()) - { - if (*r == "color.blocked") colorizeBlocked (task, base, c, merge); - else if (*r == "color.blocking") colorizeBlocking (task, base, c, merge); - else if (*r == "color.tagged") colorizeTagged (task, base, c, merge); - else if (*r == "color.active") colorizeActive (task, base, c, merge); - else if (*r == "color.scheduled") colorizeScheduled (task, base, c, merge); - else if (*r == "color.until") colorizeUntil (task, base, c, merge); - else if (*r == "color.project.none") colorizeProjectNone (task, base, c, merge); - else if (*r == "color.tag.none") colorizeTagNone (task, base, c, merge); - else if (*r == "color.due") colorizeDue (task, base, c, merge); - else if (*r == "color.due.today") colorizeDueToday (task, base, c, merge); - else if (*r == "color.overdue") colorizeOverdue (task, base, c, merge); - else if (*r == "color.recurring") colorizeRecurring (task, base, c, merge); - else if (*r == "color.completed") colorizeCompleted (task, base, c, merge); - else if (*r == "color.deleted") colorizeDeleted (task, base, c, merge); + if (base.nontrivial()) { + if (*r == "color.blocked") + colorizeBlocked(task, base, c, merge); + else if (*r == "color.blocking") + colorizeBlocking(task, base, c, merge); + else if (*r == "color.tagged") + colorizeTagged(task, base, c, merge); + else if (*r == "color.active") + colorizeActive(task, base, c, merge); + else if (*r == "color.scheduled") + colorizeScheduled(task, base, c, merge); + else if (*r == "color.until") + colorizeUntil(task, base, c, merge); + else if (*r == "color.project.none") + colorizeProjectNone(task, base, c, merge); + else if (*r == "color.tag.none") + colorizeTagNone(task, base, c, merge); + else if (*r == "color.due") + colorizeDue(task, base, c, merge); + else if (*r == "color.due.today") + colorizeDueToday(task, base, c, merge); + else if (*r == "color.overdue") + colorizeOverdue(task, base, c, merge); + else if (*r == "color.recurring") + colorizeRecurring(task, base, c, merge); + else if (*r == "color.completed") + colorizeCompleted(task, base, c, merge); + else if (*r == "color.deleted") + colorizeDeleted(task, base, c, merge); // Wildcards - else if (! r->compare (0, 10, "color.tag.", 10)) colorizeTag (task, *r, base, c, merge); - else if (! r->compare (0, 14, "color.project.", 14)) colorizeProject (task, *r, base, c, merge); - else if (! r->compare (0, 14, "color.keyword.", 14)) colorizeKeyword (task, *r, base, c, merge); - else if (! r->compare (0, 10, "color.uda.", 10)) colorizeUDA (task, *r, base, c, merge); + else if (!r->compare(0, 10, "color.tag.", 10)) + colorizeTag(task, *r, base, c, merge); + else if (!r->compare(0, 14, "color.project.", 14)) + colorizeProject(task, *r, base, c, merge); + else if (!r->compare(0, 14, "color.keyword.", 14)) + colorizeKeyword(task, *r, base, c, merge); + else if (!r->compare(0, 10, "color.uda.", 10)) + colorizeUDA(task, *r, base, c, merge); } } - } //////////////////////////////////////////////////////////////////////////////// -std::string colorizeHeader (const std::string& input) -{ - if (gsColor["color.header"].nontrivial ()) - return gsColor["color.header"].colorize (input); +std::string colorizeHeader(const std::string& input) { + if (gsColor["color.header"].nontrivial()) return gsColor["color.header"].colorize(input); return input; } //////////////////////////////////////////////////////////////////////////////// -std::string colorizeFootnote (const std::string& input) -{ - if (gsColor["color.footnote"].nontrivial ()) - return gsColor["color.footnote"].colorize (input); +std::string colorizeFootnote(const std::string& input) { + if (gsColor["color.footnote"].nontrivial()) return gsColor["color.footnote"].colorize(input); return input; } //////////////////////////////////////////////////////////////////////////////// -std::string colorizeError (const std::string& input) -{ - if (gsColor["color.error"].nontrivial ()) - return gsColor["color.error"].colorize (input); +std::string colorizeError(const std::string& input) { + if (gsColor["color.error"].nontrivial()) return gsColor["color.error"].colorize(input); return input; } //////////////////////////////////////////////////////////////////////////////// -std::string colorizeDebug (const std::string& input) -{ - if (gsColor["color.debug"].nontrivial ()) - return gsColor["color.debug"].colorize (input); +std::string colorizeDebug(const std::string& input) { + if (gsColor["color.debug"].nontrivial()) return gsColor["color.debug"].colorize(input); return input; } diff --git a/src/sort.cpp b/src/sort.cpp index 25f690fe4..4b0bee350 100644 --- a/src/sort.cpp +++ b/src/sort.cpp @@ -27,93 +27,77 @@ #include // cmake.h include header must come first -#include -#include -#include -#include -#include -#include #include #include #include -#include -#include #include +#include +#include +#include -static std::vector * global_data = nullptr; -static std::vector global_keys; -static bool sort_compare (int, int); +#include +#include +#include +#include +#include + +static std::vector* global_data = nullptr; +static std::vector global_keys; +static bool sort_compare(int, int); //////////////////////////////////////////////////////////////////////////////// -void sort_tasks ( - std::vector & data, - std::vector & order, - const std::string& keys) -{ +void sort_tasks(std::vector& data, std::vector& order, const std::string& keys) { Timer timer; global_data = &data; // Split the key defs. - global_keys = split (keys, ','); + global_keys = split(keys, ','); // Only sort if necessary. - if (order.size ()) - std::stable_sort (order.begin (), order.end (), sort_compare); + if (order.size()) std::stable_sort(order.begin(), order.end(), sort_compare); - Context::getContext ().time_sort_us += timer.total_us (); + Context::getContext().time_sort_us += timer.total_us(); } -void sort_projects ( - std::list >& sorted, - std::map & allProjects) -{ - for (auto& project : allProjects) - { - const std::vector parents = extractParents (project.first); - if (parents.size ()) - { +void sort_projects(std::list>& sorted, + std::map& allProjects) { + for (auto& project : allProjects) { + const std::vector parents = extractParents(project.first); + if (parents.size()) { // if parents exist: store iterator position of last parent - std::list >::iterator parent_pos; - for (auto& parent : parents) - { - parent_pos = std::find_if (sorted.begin (), sorted.end (), - [&parent](const std::pair & item) { return item.first == parent; }); + std::list>::iterator parent_pos; + for (auto& parent : parents) { + parent_pos = std::find_if( + sorted.begin(), sorted.end(), + [&parent](const std::pair& item) { return item.first == parent; }); // if parent does not exist yet: insert into sorted view - if (parent_pos == sorted.end ()) - sorted.emplace_back (parent, 1); + if (parent_pos == sorted.end()) sorted.emplace_back(parent, 1); } // insert new element below latest parent - sorted.insert ((parent_pos == sorted.end ()) ? parent_pos : ++parent_pos, project); - } - else - { + sorted.insert((parent_pos == sorted.end()) ? parent_pos : ++parent_pos, project); + } else { // if has no parents: simply push to end of list - sorted.push_back (project); + sorted.push_back(project); } } } -void sort_projects ( - std::list >& sorted, - std::map & allProjects) -{ - std::map allProjectsInt; - for (auto& p : allProjects) - allProjectsInt[p.first] = (int) p.second; +void sort_projects(std::list>& sorted, + std::map& allProjects) { + std::map allProjectsInt; + for (auto& p : allProjects) allProjectsInt[p.first] = (int)p.second; - sort_projects (sorted, allProjectsInt); + sort_projects(sorted, allProjectsInt); } - //////////////////////////////////////////////////////////////////////////////// // Re-implementation, using direct Task access instead of data copies that // require re-parsing. // // Essentially a static implementation of a dynamic operator<. -static bool sort_compare (int left, int right) -{ +static bool sort_compare(int left, int right) { std::string field; bool ascending; bool breakIndicator; @@ -123,205 +107,148 @@ static bool sort_compare (int left, int right) float left_real; float right_real; - for (auto& k : global_keys) - { - Context::getContext ().decomposeSortField (k, field, ascending, breakIndicator); + for (auto& k : global_keys) { + Context::getContext().decomposeSortField(k, field, ascending, breakIndicator); // Urgency. - if (field == "urgency") - { - left_real = (*global_data)[left].urgency (); - right_real = (*global_data)[right].urgency (); + if (field == "urgency") { + left_real = (*global_data)[left].urgency(); + right_real = (*global_data)[right].urgency(); - if (left_real == right_real) - continue; + if (left_real == right_real) continue; - return ascending ? (left_real < right_real) - : (left_real > right_real); + return ascending ? (left_real < right_real) : (left_real > right_real); } // Number. - else if (field == "id") - { - left_number = (*global_data)[left].id; + else if (field == "id") { + left_number = (*global_data)[left].id; right_number = (*global_data)[right].id; - if (left_number == right_number) - continue; + if (left_number == right_number) continue; - return ascending ? (left_number < right_number) - : (left_number > right_number); + return ascending ? (left_number < right_number) : (left_number > right_number); } // String. - else if (field == "description" || - field == "project" || - field == "status" || - field == "tags" || - field == "uuid" || - field == "parent" || - field == "imask" || - field == "mask") - { - auto left_string = (*global_data)[left].get_ref (field); - auto right_string = (*global_data)[right].get_ref (field); + else if (field == "description" || field == "project" || field == "status" || field == "tags" || + field == "uuid" || field == "parent" || field == "imask" || field == "mask") { + auto left_string = (*global_data)[left].get_ref(field); + auto right_string = (*global_data)[right].get_ref(field); - if (left_string == right_string) - continue; + if (left_string == right_string) continue; - return ascending ? (left_string < right_string) - : (left_string > right_string); + return ascending ? (left_string < right_string) : (left_string > right_string); } // Due Date. - else if (field == "due" || - field == "end" || - field == "entry" || - field == "start" || - field == "until" || - field == "wait" || - field == "modified" || - field == "scheduled") - { - auto left_string = (*global_data)[left].get_ref (field); - auto right_string = (*global_data)[right].get_ref (field); + else if (field == "due" || field == "end" || field == "entry" || field == "start" || + field == "until" || field == "wait" || field == "modified" || field == "scheduled") { + auto left_string = (*global_data)[left].get_ref(field); + auto right_string = (*global_data)[right].get_ref(field); - if (left_string != "" && right_string == "") - return true; + if (left_string != "" && right_string == "") return true; - if (left_string == "" && right_string != "") - return false; + if (left_string == "" && right_string != "") return false; - if (left_string == right_string) - continue; + if (left_string == right_string) continue; - return ascending ? (left_string < right_string) - : (left_string > right_string); + return ascending ? (left_string < right_string) : (left_string > right_string); } // Depends string. - else if (field == "depends") - { + else if (field == "depends") { // Raw data is an un-sorted list of UUIDs. We just need a stable // sort, so we sort them lexically. - auto left_deps = (*global_data)[left].getDependencyUUIDs (); + auto left_deps = (*global_data)[left].getDependencyUUIDs(); std::sort(left_deps.begin(), left_deps.end()); - auto right_deps = (*global_data)[right].getDependencyUUIDs (); + auto right_deps = (*global_data)[right].getDependencyUUIDs(); std::sort(right_deps.begin(), right_deps.end()); - if (left_deps == right_deps) - continue; + if (left_deps == right_deps) continue; - if (left_deps.size () == 0 && right_deps.size () > 0) - return ascending; + if (left_deps.size() == 0 && right_deps.size() > 0) return ascending; - if (left_deps.size () > 0 && right_deps.size () == 0) - return !ascending; + if (left_deps.size() > 0 && right_deps.size() == 0) return !ascending; // Sort on the first dependency. - left_number = Context::getContext ().tdb2.id (left_deps[0]); - right_number = Context::getContext ().tdb2.id (right_deps[0]); + left_number = Context::getContext().tdb2.id(left_deps[0]); + right_number = Context::getContext().tdb2.id(right_deps[0]); - if (left_number == right_number) - continue; + if (left_number == right_number) continue; - return ascending ? (left_number < right_number) - : (left_number > right_number); + return ascending ? (left_number < right_number) : (left_number > right_number); } // Duration. - else if (field == "recur") - { - auto left_string = (*global_data)[left].get_ref (field); - auto right_string = (*global_data)[right].get_ref (field); + else if (field == "recur") { + auto left_string = (*global_data)[left].get_ref(field); + auto right_string = (*global_data)[right].get_ref(field); - if (left_string == right_string) - continue; + if (left_string == right_string) continue; - Duration left_duration (left_string); - Duration right_duration (right_string); - return ascending ? (left_duration < right_duration) - : (left_duration > right_duration); + Duration left_duration(left_string); + Duration right_duration(right_string); + return ascending ? (left_duration < right_duration) : (left_duration > right_duration); } // UDAs. - else if ((column = Context::getContext ().columns[field]) != nullptr) - { - std::string type = column->type (); - if (type == "numeric") - { - auto left_real = strtof (((*global_data)[left].get_ref (field)).c_str (), nullptr); - auto right_real = strtof (((*global_data)[right].get_ref (field)).c_str (), nullptr); + else if ((column = Context::getContext().columns[field]) != nullptr) { + std::string type = column->type(); + if (type == "numeric") { + auto left_real = strtof(((*global_data)[left].get_ref(field)).c_str(), nullptr); + auto right_real = strtof(((*global_data)[right].get_ref(field)).c_str(), nullptr); - if (left_real == right_real) - continue; + if (left_real == right_real) continue; - return ascending ? (left_real < right_real) - : (left_real > right_real); - } - else if (type == "string") - { - auto left_string = (*global_data)[left].get_ref (field); - auto right_string = (*global_data)[right].get_ref (field); + return ascending ? (left_real < right_real) : (left_real > right_real); + } else if (type == "string") { + auto left_string = (*global_data)[left].get_ref(field); + auto right_string = (*global_data)[right].get_ref(field); - if (left_string == right_string) - continue; + if (left_string == right_string) continue; // UDAs of the type string can have custom sort orders, which need to be considered. - auto order = Task::customOrder.find (field); - if (order != Task::customOrder.end ()) - { + auto order = Task::customOrder.find(field); + if (order != Task::customOrder.end()) { // Guaranteed to be found, because of ColUDA::validate (). - auto posLeft = std::find (order->second.begin (), order->second.end (), left_string); - auto posRight = std::find (order->second.begin (), order->second.end (), right_string); + auto posLeft = std::find(order->second.begin(), order->second.end(), left_string); + auto posRight = std::find(order->second.begin(), order->second.end(), right_string); return ascending ? (posLeft < posRight) : (posLeft > posRight); - } - else - { + } else { // Empty values are unconditionally last, if no custom order was specified. if (left_string == "") return false; else if (right_string == "") return true; - return ascending ? (left_string < right_string) - : (left_string > right_string); + return ascending ? (left_string < right_string) : (left_string > right_string); } } - else if (type == "date") - { - auto left_string = (*global_data)[left].get_ref (field); - auto right_string = (*global_data)[right].get_ref (field); + else if (type == "date") { + auto left_string = (*global_data)[left].get_ref(field); + auto right_string = (*global_data)[right].get_ref(field); - if (left_string != "" && right_string == "") - return true; + if (left_string != "" && right_string == "") return true; - if (left_string == "" && right_string != "") - return false; + if (left_string == "" && right_string != "") return false; - if (left_string == right_string) - continue; + if (left_string == right_string) continue; - return ascending ? (left_string < right_string) - : (left_string > right_string); + return ascending ? (left_string < right_string) : (left_string > right_string); + } else if (type == "duration") { + auto left_string = (*global_data)[left].get_ref(field); + auto right_string = (*global_data)[right].get_ref(field); + + if (left_string == right_string) continue; + + Duration left_duration(left_string); + Duration right_duration(right_string); + return ascending ? (left_duration < right_duration) : (left_duration > right_duration); } - else if (type == "duration") - { - auto left_string = (*global_data)[left].get_ref (field); - auto right_string = (*global_data)[right].get_ref (field); - - if (left_string == right_string) - continue; - - Duration left_duration (left_string); - Duration right_duration (right_string); - return ascending ? (left_duration < right_duration) - : (left_duration > right_duration); - } - } - else - throw format ("The '{1}' column is not a valid sort field.", field); + } else + throw format("The '{1}' column is not a valid sort field.", field); } return false; diff --git a/src/tc/Replica.cpp b/src/tc/Replica.cpp index e1a2fb1ce..a90ac2e0b 100644 --- a/src/tc/Replica.cpp +++ b/src/tc/Replica.cpp @@ -28,20 +28,19 @@ // cmake.h include header must come first #include + +#include + #include "tc/Replica.h" -#include "tc/Task.h" #include "tc/Server.h" +#include "tc/Task.h" #include "tc/WorkingSet.h" #include "tc/util.h" -#include using namespace tc::ffi; //////////////////////////////////////////////////////////////////////////////// -tc::ReplicaGuard::ReplicaGuard (Replica &replica, Task &task) : - replica(replica), - task(task) -{ +tc::ReplicaGuard::ReplicaGuard(Replica &replica, Task &task) : replica(replica), task(task) { // "steal" the reference from the Replica and store it locally, so that any // attempt to use the Replica will fail tcreplica = replica.inner.release(); @@ -49,228 +48,196 @@ tc::ReplicaGuard::ReplicaGuard (Replica &replica, Task &task) : } //////////////////////////////////////////////////////////////////////////////// -tc::ReplicaGuard::~ReplicaGuard () -{ +tc::ReplicaGuard::~ReplicaGuard() { task.to_immut(); // return the reference to the Replica. replica.inner.reset(tcreplica); } //////////////////////////////////////////////////////////////////////////////// -tc::Replica::Replica () -{ - inner = unique_tcreplica_ptr ( - tc_replica_new_in_memory (), - [](TCReplica* rep) { tc_replica_free (rep); }); +tc::Replica::Replica() { + inner = unique_tcreplica_ptr(tc_replica_new_in_memory(), + [](TCReplica *rep) { tc_replica_free(rep); }); } //////////////////////////////////////////////////////////////////////////////// -tc::Replica::Replica (Replica &&other) noexcept -{ +tc::Replica::Replica(Replica &&other) noexcept { // move inner from other - inner = unique_tcreplica_ptr ( - other.inner.release (), - [](TCReplica* rep) { tc_replica_free (rep); }); + inner = unique_tcreplica_ptr(other.inner.release(), [](TCReplica *rep) { tc_replica_free(rep); }); } //////////////////////////////////////////////////////////////////////////////// -tc::Replica& tc::Replica::operator= (Replica &&other) noexcept -{ +tc::Replica &tc::Replica::operator=(Replica &&other) noexcept { if (this != &other) { // move inner from other - inner = unique_tcreplica_ptr ( - other.inner.release (), - [](TCReplica* rep) { tc_replica_free (rep); }); + inner = + unique_tcreplica_ptr(other.inner.release(), [](TCReplica *rep) { tc_replica_free(rep); }); } return *this; } //////////////////////////////////////////////////////////////////////////////// -tc::Replica::Replica (const std::string& dir, bool create_if_missing) -{ - TCString path = tc_string_borrow (dir.c_str ()); +tc::Replica::Replica(const std::string &dir, bool create_if_missing) { + TCString path = tc_string_borrow(dir.c_str()); TCString error; - auto tcreplica = tc_replica_new_on_disk (path, create_if_missing, &error); + auto tcreplica = tc_replica_new_on_disk(path, create_if_missing, &error); if (!tcreplica) { - auto errmsg = format ("Could not create replica at {1}: {2}", dir, tc_string_content (&error)); - tc_string_free (&error); + auto errmsg = format("Could not create replica at {1}: {2}", dir, tc_string_content(&error)); + tc_string_free(&error); throw errmsg; } - inner = unique_tcreplica_ptr ( - tcreplica, - [](TCReplica* rep) { tc_replica_free (rep); }); + inner = unique_tcreplica_ptr(tcreplica, [](TCReplica *rep) { tc_replica_free(rep); }); } //////////////////////////////////////////////////////////////////////////////// -tc::WorkingSet tc::Replica::working_set () -{ - TCWorkingSet *tcws = tc_replica_working_set (&*inner); +tc::WorkingSet tc::Replica::working_set() { + TCWorkingSet *tcws = tc_replica_working_set(&*inner); if (!tcws) { - throw replica_error (); + throw replica_error(); } - return WorkingSet {tcws}; + return WorkingSet{tcws}; } //////////////////////////////////////////////////////////////////////////////// -std::optional tc::Replica::get_task (const std::string &uuid) -{ - TCTask *tctask = tc_replica_get_task (&*inner, uuid2tc (uuid)); +std::optional tc::Replica::get_task(const std::string &uuid) { + TCTask *tctask = tc_replica_get_task(&*inner, uuid2tc(uuid)); if (!tctask) { - auto error = tc_replica_error (&*inner); + auto error = tc_replica_error(&*inner); if (error.ptr) { - throw replica_error (error); + throw replica_error(error); } else { return std::nullopt; } } - return std::make_optional (Task (tctask)); + return std::make_optional(Task(tctask)); } //////////////////////////////////////////////////////////////////////////////// -tc::Task tc::Replica::new_task (tc::Status status, const std::string &description) -{ - TCTask *tctask = tc_replica_new_task (&*inner, (tc::ffi::TCStatus)status, string2tc (description)); +tc::Task tc::Replica::new_task(tc::Status status, const std::string &description) { + TCTask *tctask = tc_replica_new_task(&*inner, (tc::ffi::TCStatus)status, string2tc(description)); if (!tctask) { - throw replica_error (); + throw replica_error(); } - return Task (tctask); + return Task(tctask); } //////////////////////////////////////////////////////////////////////////////// -tc::Task tc::Replica::import_task_with_uuid (const std::string &uuid) -{ - TCTask *tctask = tc_replica_import_task_with_uuid (&*inner, uuid2tc (uuid)); +tc::Task tc::Replica::import_task_with_uuid(const std::string &uuid) { + TCTask *tctask = tc_replica_import_task_with_uuid(&*inner, uuid2tc(uuid)); if (!tctask) { - throw replica_error (); + throw replica_error(); } - return Task (tctask); + return Task(tctask); } //////////////////////////////////////////////////////////////////////////////// -void tc::Replica::delete_task (const std::string &uuid) -{ - auto res = tc_replica_delete_task (&*inner, uuid2tc (uuid)); +void tc::Replica::delete_task(const std::string &uuid) { + auto res = tc_replica_delete_task(&*inner, uuid2tc(uuid)); if (res != TC_RESULT_OK) { - throw replica_error (); + throw replica_error(); } } //////////////////////////////////////////////////////////////////////////////// -void tc::Replica::expire_tasks () -{ - auto res = tc_replica_expire_tasks (&*inner); +void tc::Replica::expire_tasks() { + auto res = tc_replica_expire_tasks(&*inner); if (res != TC_RESULT_OK) { - throw replica_error (); + throw replica_error(); } } //////////////////////////////////////////////////////////////////////////////// -void tc::Replica::sync (Server server, bool avoid_snapshots) -{ +void tc::Replica::sync(Server server, bool avoid_snapshots) { // The server remains owned by this function, per tc_replica_sync docs. - auto res = tc_replica_sync (&*inner, server.inner.get(), avoid_snapshots); + auto res = tc_replica_sync(&*inner, server.inner.get(), avoid_snapshots); if (res != TC_RESULT_OK) { - throw replica_error (); + throw replica_error(); } } //////////////////////////////////////////////////////////////////////////////// -TCReplicaOpList tc::Replica::get_undo_ops () -{ - return tc_replica_get_undo_ops(&*inner); -} +TCReplicaOpList tc::Replica::get_undo_ops() { return tc_replica_get_undo_ops(&*inner); } //////////////////////////////////////////////////////////////////////////////// -void tc::Replica::commit_undo_ops (TCReplicaOpList tc_undo_ops, int32_t *undone_out) -{ - auto res = tc_replica_commit_undo_ops (&*inner, tc_undo_ops, undone_out); +void tc::Replica::commit_undo_ops(TCReplicaOpList tc_undo_ops, int32_t *undone_out) { + auto res = tc_replica_commit_undo_ops(&*inner, tc_undo_ops, undone_out); if (res != TC_RESULT_OK) { - throw replica_error (); + throw replica_error(); } } //////////////////////////////////////////////////////////////////////////////// -void tc::Replica::free_replica_ops (TCReplicaOpList tc_undo_ops) -{ +void tc::Replica::free_replica_ops(TCReplicaOpList tc_undo_ops) { tc_replica_op_list_free(&tc_undo_ops); } //////////////////////////////////////////////////////////////////////////////// -std::string tc::Replica::get_op_uuid(TCReplicaOp &tc_replica_op) const -{ +std::string tc::Replica::get_op_uuid(TCReplicaOp &tc_replica_op) const { TCString uuid = tc_replica_op_get_uuid(&tc_replica_op); return tc2string(uuid); } //////////////////////////////////////////////////////////////////////////////// -std::string tc::Replica::get_op_property(TCReplicaOp &tc_replica_op) const -{ +std::string tc::Replica::get_op_property(TCReplicaOp &tc_replica_op) const { TCString property = tc_replica_op_get_property(&tc_replica_op); return tc2string(property); } //////////////////////////////////////////////////////////////////////////////// -std::string tc::Replica::get_op_value(TCReplicaOp &tc_replica_op) const -{ +std::string tc::Replica::get_op_value(TCReplicaOp &tc_replica_op) const { TCString value = tc_replica_op_get_value(&tc_replica_op); return tc2string(value); } //////////////////////////////////////////////////////////////////////////////// -std::string tc::Replica::get_op_old_value(TCReplicaOp &tc_replica_op) const -{ +std::string tc::Replica::get_op_old_value(TCReplicaOp &tc_replica_op) const { TCString old_value = tc_replica_op_get_old_value(&tc_replica_op); return tc2string(old_value); } //////////////////////////////////////////////////////////////////////////////// -std::string tc::Replica::get_op_timestamp(TCReplicaOp &tc_replica_op) const -{ +std::string tc::Replica::get_op_timestamp(TCReplicaOp &tc_replica_op) const { TCString timestamp = tc_replica_op_get_timestamp(&tc_replica_op); return tc2string(timestamp); } //////////////////////////////////////////////////////////////////////////////// -std::string tc::Replica::get_op_old_task_description(TCReplicaOp &tc_replica_op) const -{ +std::string tc::Replica::get_op_old_task_description(TCReplicaOp &tc_replica_op) const { TCString description = tc_replica_op_get_old_task_description(&tc_replica_op); return tc2string(description); } //////////////////////////////////////////////////////////////////////////////// -int64_t tc::Replica::num_local_operations () -{ - auto num = tc_replica_num_local_operations (&*inner); +int64_t tc::Replica::num_local_operations() { + auto num = tc_replica_num_local_operations(&*inner); if (num < 0) { - throw replica_error (); + throw replica_error(); } return num; } //////////////////////////////////////////////////////////////////////////////// -int64_t tc::Replica::num_undo_points () -{ - auto num = tc_replica_num_undo_points (&*inner); +int64_t tc::Replica::num_undo_points() { + auto num = tc_replica_num_undo_points(&*inner); if (num < 0) { - throw replica_error (); + throw replica_error(); } return num; } //////////////////////////////////////////////////////////////////////////////// -std::vector tc::Replica::all_tasks () -{ - TCTaskList tasks = tc_replica_all_tasks (&*inner); +std::vector tc::Replica::all_tasks() { + TCTaskList tasks = tc_replica_all_tasks(&*inner); if (!tasks.items) { - throw replica_error (); + throw replica_error(); } - std::vector all; - all.reserve (tasks.len); + std::vector all; + all.reserve(tasks.len); for (size_t i = 0; i < tasks.len; i++) { - auto tctask = tc_task_list_take (&tasks, i); + auto tctask = tc_task_list_take(&tasks, i); if (tctask) { - all.push_back (Task (tctask)); + all.push_back(Task(tctask)); } } @@ -278,33 +245,28 @@ std::vector tc::Replica::all_tasks () } //////////////////////////////////////////////////////////////////////////////// -void tc::Replica::rebuild_working_set (bool force) -{ - auto res = tc_replica_rebuild_working_set (&*inner, force); +void tc::Replica::rebuild_working_set(bool force) { + auto res = tc_replica_rebuild_working_set(&*inner, force); if (res != TC_RESULT_OK) { - throw replica_error (); + throw replica_error(); } } //////////////////////////////////////////////////////////////////////////////// -tc::ReplicaGuard tc::Replica::mutate_task (tc::Task &task) { - return ReplicaGuard(*this, task); -} +tc::ReplicaGuard tc::Replica::mutate_task(tc::Task &task) { return ReplicaGuard(*this, task); } //////////////////////////////////////////////////////////////////////////////// -std::string tc::Replica::replica_error () { - return replica_error (tc_replica_error (&*inner)); -} +std::string tc::Replica::replica_error() { return replica_error(tc_replica_error(&*inner)); } //////////////////////////////////////////////////////////////////////////////// -std::string tc::Replica::replica_error (TCString error) { +std::string tc::Replica::replica_error(TCString error) { std::string errmsg; if (!error.ptr) { - errmsg = std::string ("Unknown TaskChampion error"); + errmsg = std::string("Unknown TaskChampion error"); } else { - errmsg = std::string (tc_string_content (&error)); + errmsg = std::string(tc_string_content(&error)); } - tc_string_free (&error); + tc_string_free(&error); return errmsg; } diff --git a/src/tc/Replica.h b/src/tc/Replica.h index 4b0ff3eda..8dd3ef188 100644 --- a/src/tc/Replica.h +++ b/src/tc/Replica.h @@ -27,102 +27,101 @@ #ifndef INCLUDED_TC_REPLICA #define INCLUDED_TC_REPLICA -#include #include #include #include +#include #include -#include "tc/ffi.h" + #include "tc/Task.h" +#include "tc/ffi.h" namespace tc { - class Task; - class WorkingSet; - class Server; +class Task; +class WorkingSet; +class Server; - // a unique_ptr to a TCReplica which will automatically free the value when - // it goes out of scope. - using unique_tcreplica_ptr = std::unique_ptr< - tc::ffi::TCReplica, - std::function>; +// a unique_ptr to a TCReplica which will automatically free the value when +// it goes out of scope. +using unique_tcreplica_ptr = + std::unique_ptr>; - // ReplicaGuard uses RAII to ensure that a Replica is not accessed while it - // is mutably borrowed (specifically, to make a task mutable). - class ReplicaGuard { - protected: - friend class Replica; - explicit ReplicaGuard (Replica &, Task &); +// ReplicaGuard uses RAII to ensure that a Replica is not accessed while it +// is mutably borrowed (specifically, to make a task mutable). +class ReplicaGuard { + protected: + friend class Replica; + explicit ReplicaGuard(Replica &, Task &); - public: - ~ReplicaGuard(); + public: + ~ReplicaGuard(); - // No moving or copying allowed - ReplicaGuard (const ReplicaGuard &) = delete; - ReplicaGuard &operator=(const ReplicaGuard &) = delete; - ReplicaGuard (ReplicaGuard &&) = delete; - ReplicaGuard &operator=(Replica &&) = delete; + // No moving or copying allowed + ReplicaGuard(const ReplicaGuard &) = delete; + ReplicaGuard &operator=(const ReplicaGuard &) = delete; + ReplicaGuard(ReplicaGuard &&) = delete; + ReplicaGuard &operator=(Replica &&) = delete; - private: - Replica &replica; - tc::ffi::TCReplica *tcreplica; - Task &task; - }; + private: + Replica &replica; + tc::ffi::TCReplica *tcreplica; + Task &task; +}; - // Replica wraps the TCReplica type, managing its memory, errors, and so on. - // - // Except as noted, method names match the suffix to `tc_replica_..`. - class Replica - { - public: - Replica (); // tc_replica_new_in_memory - Replica (const std::string& dir, bool create_if_missing); // tc_replica_new_on_disk +// Replica wraps the TCReplica type, managing its memory, errors, and so on. +// +// Except as noted, method names match the suffix to `tc_replica_..`. +class Replica { + public: + Replica(); // tc_replica_new_in_memory + Replica(const std::string &dir, bool create_if_missing); // tc_replica_new_on_disk - // This object "owns" inner, so copy is not allowed. - Replica (const Replica &) = delete; - Replica &operator=(const Replica &) = delete; + // This object "owns" inner, so copy is not allowed. + Replica(const Replica &) = delete; + Replica &operator=(const Replica &) = delete; - // Explicit move constructor and assignment - Replica (Replica &&) noexcept; - Replica &operator=(Replica &&) noexcept; + // Explicit move constructor and assignment + Replica(Replica &&) noexcept; + Replica &operator=(Replica &&) noexcept; - std::vector all_tasks (); -// TODO: struct TCUuidList tc_replica_all_task_uuids(struct TCReplica *rep); - tc::WorkingSet working_set (); - std::optional get_task (const std::string &uuid); - tc::Task new_task (Status status, const std::string &description); - tc::Task import_task_with_uuid (const std::string &uuid); - void delete_task (const std::string &uuid); -// TODO: struct TCTask *tc_replica_import_task_with_uuid(struct TCReplica *rep, struct TCUuid tcuuid); - void expire_tasks(); - void sync(Server server, bool avoid_snapshots); - tc::ffi::TCReplicaOpList get_undo_ops (); - void commit_undo_ops (tc::ffi::TCReplicaOpList tc_undo_ops, int32_t *undone_out); - void free_replica_ops (tc::ffi::TCReplicaOpList tc_undo_ops); - std::string get_op_uuid(tc::ffi::TCReplicaOp &tc_replica_op) const; - std::string get_op_property(tc::ffi::TCReplicaOp &tc_replica_op) const; - std::string get_op_value(tc::ffi::TCReplicaOp &tc_replica_op) const; - std::string get_op_old_value(tc::ffi::TCReplicaOp &tc_replica_op) const; - std::string get_op_timestamp(tc::ffi::TCReplicaOp &tc_replica_op) const; - std::string get_op_old_task_description(tc::ffi::TCReplicaOp &tc_replica_op) const; - int64_t num_local_operations (); - int64_t num_undo_points (); -// TODO: TCResult tc_replica_add_undo_point(struct TCReplica *rep, bool force); - void rebuild_working_set (bool force); + std::vector all_tasks(); + // TODO: struct TCUuidList tc_replica_all_task_uuids(struct TCReplica *rep); + tc::WorkingSet working_set(); + std::optional get_task(const std::string &uuid); + tc::Task new_task(Status status, const std::string &description); + tc::Task import_task_with_uuid(const std::string &uuid); + void delete_task(const std::string &uuid); + // TODO: struct TCTask *tc_replica_import_task_with_uuid(struct TCReplica *rep, struct TCUuid + // tcuuid); + void expire_tasks(); + void sync(Server server, bool avoid_snapshots); + tc::ffi::TCReplicaOpList get_undo_ops(); + void commit_undo_ops(tc::ffi::TCReplicaOpList tc_undo_ops, int32_t *undone_out); + void free_replica_ops(tc::ffi::TCReplicaOpList tc_undo_ops); + std::string get_op_uuid(tc::ffi::TCReplicaOp &tc_replica_op) const; + std::string get_op_property(tc::ffi::TCReplicaOp &tc_replica_op) const; + std::string get_op_value(tc::ffi::TCReplicaOp &tc_replica_op) const; + std::string get_op_old_value(tc::ffi::TCReplicaOp &tc_replica_op) const; + std::string get_op_timestamp(tc::ffi::TCReplicaOp &tc_replica_op) const; + std::string get_op_old_task_description(tc::ffi::TCReplicaOp &tc_replica_op) const; + int64_t num_local_operations(); + int64_t num_undo_points(); + // TODO: TCResult tc_replica_add_undo_point(struct TCReplica *rep, bool force); + void rebuild_working_set(bool force); - ReplicaGuard mutate_task(tc::Task &); - void immut_task(tc::Task &); + ReplicaGuard mutate_task(tc::Task &); + void immut_task(tc::Task &); - protected: - friend class ReplicaGuard; - unique_tcreplica_ptr inner; - - // construct an error message from tc_replica_error, or from the given - // string retrieved from tc_replica_error. - std::string replica_error (); - std::string replica_error (tc::ffi::TCString string); - }; -} + protected: + friend class ReplicaGuard; + unique_tcreplica_ptr inner; + // construct an error message from tc_replica_error, or from the given + // string retrieved from tc_replica_error. + std::string replica_error(); + std::string replica_error(tc::ffi::TCString string); +}; +} // namespace tc #endif //////////////////////////////////////////////////////////////////////////////// diff --git a/src/tc/Server.cpp b/src/tc/Server.cpp index 5e43d1c2e..e5adef9dd 100644 --- a/src/tc/Server.cpp +++ b/src/tc/Server.cpp @@ -28,95 +28,80 @@ // cmake.h include header must come first #include + #include "tc/Server.h" #include "tc/util.h" using namespace tc::ffi; //////////////////////////////////////////////////////////////////////////////// -tc::Server -tc::Server::new_local (const std::string &server_dir) -{ - TCString tc_server_dir = tc_string_borrow (server_dir.c_str ()); +tc::Server tc::Server::new_local(const std::string &server_dir) { + TCString tc_server_dir = tc_string_borrow(server_dir.c_str()); TCString error; - auto tcserver = tc_server_new_local (tc_server_dir, &error); + auto tcserver = tc_server_new_local(tc_server_dir, &error); if (!tcserver) { - std::string errmsg = format ("Could not configure local server at {1}: {2}", - server_dir, tc_string_content (&error)); - tc_string_free (&error); + std::string errmsg = format("Could not configure local server at {1}: {2}", server_dir, + tc_string_content(&error)); + tc_string_free(&error); throw errmsg; } - return Server (unique_tcserver_ptr ( - tcserver, - [](TCServer* rep) { tc_server_free (rep); })); + return Server(unique_tcserver_ptr(tcserver, [](TCServer *rep) { tc_server_free(rep); })); } //////////////////////////////////////////////////////////////////////////////// -tc::Server -tc::Server::new_sync (const std::string &url, const std::string &client_id, const std::string &encryption_secret) -{ - TCString tc_url = tc_string_borrow (url.c_str ()); - TCString tc_client_id = tc_string_borrow (client_id.c_str ()); - TCString tc_encryption_secret = tc_string_borrow (encryption_secret.c_str ()); +tc::Server tc::Server::new_sync(const std::string &url, const std::string &client_id, + const std::string &encryption_secret) { + TCString tc_url = tc_string_borrow(url.c_str()); + TCString tc_client_id = tc_string_borrow(client_id.c_str()); + TCString tc_encryption_secret = tc_string_borrow(encryption_secret.c_str()); TCUuid tc_client_uuid; if (tc_uuid_from_str(tc_client_id, &tc_client_uuid) != TC_RESULT_OK) { tc_string_free(&tc_url); tc_string_free(&tc_encryption_secret); - throw format ("client_id '{1}' is not a valid UUID", client_id); + throw format("client_id '{1}' is not a valid UUID", client_id); } TCString error; - auto tcserver = tc_server_new_sync (tc_url, tc_client_uuid, tc_encryption_secret, &error); + auto tcserver = tc_server_new_sync(tc_url, tc_client_uuid, tc_encryption_secret, &error); if (!tcserver) { - std::string errmsg = format ("Could not configure connection to server at {1}: {2}", - url, tc_string_content (&error)); - tc_string_free (&error); + std::string errmsg = format("Could not configure connection to server at {1}: {2}", url, + tc_string_content(&error)); + tc_string_free(&error); throw errmsg; } - return Server (unique_tcserver_ptr ( - tcserver, - [](TCServer* rep) { tc_server_free (rep); })); + return Server(unique_tcserver_ptr(tcserver, [](TCServer *rep) { tc_server_free(rep); })); } //////////////////////////////////////////////////////////////////////////////// -tc::Server -tc::Server::new_gcp (const std::string &bucket, const std::string &credential_path, const std::string &encryption_secret) -{ - TCString tc_bucket = tc_string_borrow (bucket.c_str ()); - TCString tc_encryption_secret = tc_string_borrow (encryption_secret.c_str ()); - TCString tc_credential_path = tc_string_borrow (credential_path.c_str ()); +tc::Server tc::Server::new_gcp(const std::string &bucket, const std::string &credential_path, + const std::string &encryption_secret) { + TCString tc_bucket = tc_string_borrow(bucket.c_str()); + TCString tc_encryption_secret = tc_string_borrow(encryption_secret.c_str()); + TCString tc_credential_path = tc_string_borrow(credential_path.c_str()); TCString error; - auto tcserver = tc_server_new_gcp (tc_bucket, tc_credential_path, tc_encryption_secret, &error); + auto tcserver = tc_server_new_gcp(tc_bucket, tc_credential_path, tc_encryption_secret, &error); if (!tcserver) { - std::string errmsg = format ("Could not configure connection to GCP bucket {1}: {2}", - bucket, tc_string_content (&error)); - tc_string_free (&error); + std::string errmsg = format("Could not configure connection to GCP bucket {1}: {2}", bucket, + tc_string_content(&error)); + tc_string_free(&error); throw errmsg; } - return Server (unique_tcserver_ptr ( - tcserver, - [](TCServer* rep) { tc_server_free (rep); })); + return Server(unique_tcserver_ptr(tcserver, [](TCServer *rep) { tc_server_free(rep); })); } //////////////////////////////////////////////////////////////////////////////// -tc::Server::Server (tc::Server &&other) noexcept -{ +tc::Server::Server(tc::Server &&other) noexcept { // move inner from other - inner = unique_tcserver_ptr ( - other.inner.release (), - [](TCServer* rep) { tc_server_free (rep); }); + inner = unique_tcserver_ptr(other.inner.release(), [](TCServer *rep) { tc_server_free(rep); }); } //////////////////////////////////////////////////////////////////////////////// -tc::Server& tc::Server::operator= (tc::Server &&other) noexcept -{ +tc::Server &tc::Server::operator=(tc::Server &&other) noexcept { if (this != &other) { // move inner from other - inner = unique_tcserver_ptr ( - other.inner.release (), - [](TCServer* rep) { tc_server_free (rep); }); + inner = unique_tcserver_ptr(other.inner.release(), [](TCServer *rep) { tc_server_free(rep); }); } return *this; } diff --git a/src/tc/Server.h b/src/tc/Server.h index bc5266b4d..489d73425 100644 --- a/src/tc/Server.h +++ b/src/tc/Server.h @@ -27,59 +27,59 @@ #ifndef INCLUDED_TC_SERVER #define INCLUDED_TC_SERVER -#include #include #include #include +#include #include + #include "tc/ffi.h" namespace tc { - // a unique_ptr to a TCServer which will automatically free the value when - // it goes out of scope. - using unique_tcserver_ptr = std::unique_ptr< - tc::ffi::TCServer, - std::function>; +// a unique_ptr to a TCServer which will automatically free the value when +// it goes out of scope. +using unique_tcserver_ptr = + std::unique_ptr>; - // Server wraps the TCServer type, managing its memory, errors, and so on. - // - // Except as noted, method names match the suffix to `tc_server_..`. - class Server - { - public: - // Construct a null server - Server () = default; +// Server wraps the TCServer type, managing its memory, errors, and so on. +// +// Except as noted, method names match the suffix to `tc_server_..`. +class Server { + public: + // Construct a null server + Server() = default; - // Construct a local server (tc_server_new_local). - static Server new_local (const std::string& server_dir); + // Construct a local server (tc_server_new_local). + static Server new_local(const std::string &server_dir); - // Construct a remote server (tc_server_new_sync). - static Server new_sync (const std::string &url, const std::string &client_id, const std::string &encryption_secret); + // Construct a remote server (tc_server_new_sync). + static Server new_sync(const std::string &url, const std::string &client_id, + const std::string &encryption_secret); - // Construct a GCP server (tc_server_new_gcp). - static Server new_gcp (const std::string &bucket, const std::string &credential_path, const std::string &encryption_secret); + // Construct a GCP server (tc_server_new_gcp). + static Server new_gcp(const std::string &bucket, const std::string &credential_path, + const std::string &encryption_secret); - // This object "owns" inner, so copy is not allowed. - Server (const Server &) = delete; - Server &operator=(const Server &) = delete; + // This object "owns" inner, so copy is not allowed. + Server(const Server &) = delete; + Server &operator=(const Server &) = delete; - // Explicit move constructor and assignment - Server (Server &&) noexcept; - Server &operator=(Server &&) noexcept; + // Explicit move constructor and assignment + Server(Server &&) noexcept; + Server &operator=(Server &&) noexcept; - protected: - Server (unique_tcserver_ptr inner) : inner(std::move(inner)) {}; + protected: + Server(unique_tcserver_ptr inner) : inner(std::move(inner)) {}; - unique_tcserver_ptr inner; + unique_tcserver_ptr inner; - // Replica accesses the inner pointer to call tc_replica_sync - friend class Replica; - - // construct an error message from the given string. - std::string server_error (tc::ffi::TCString string); - }; -} + // Replica accesses the inner pointer to call tc_replica_sync + friend class Replica; + // construct an error message from the given string. + std::string server_error(tc::ffi::TCString string); +}; +} // namespace tc #endif //////////////////////////////////////////////////////////////////////////////// diff --git a/src/tc/Task.cpp b/src/tc/Task.cpp index 7b3a4e217..5b5e5fd9a 100644 --- a/src/tc/Task.cpp +++ b/src/tc/Task.cpp @@ -28,72 +28,55 @@ // cmake.h include header must come first #include + #include "tc/Task.h" #include "tc/util.h" using namespace tc::ffi; //////////////////////////////////////////////////////////////////////////////// -tc::Task::Task (TCTask *tctask) -{ - inner = unique_tctask_ptr( - tctask, - [](TCTask* task) { tc_task_free(task); }); +tc::Task::Task(TCTask* tctask) { + inner = unique_tctask_ptr(tctask, [](TCTask* task) { tc_task_free(task); }); } //////////////////////////////////////////////////////////////////////////////// -tc::Task::Task (Task &&other) noexcept -{ +tc::Task::Task(Task&& other) noexcept { // move inner from other - inner = unique_tctask_ptr( - other.inner.release(), - [](TCTask* task) { tc_task_free(task); }); + inner = unique_tctask_ptr(other.inner.release(), [](TCTask* task) { tc_task_free(task); }); } //////////////////////////////////////////////////////////////////////////////// -tc::Task& tc::Task::operator= (Task &&other) noexcept -{ +tc::Task& tc::Task::operator=(Task&& other) noexcept { if (this != &other) { // move inner from other - inner = unique_tctask_ptr( - other.inner.release(), - [](TCTask* task) { tc_task_free(task); }); + inner = unique_tctask_ptr(other.inner.release(), [](TCTask* task) { tc_task_free(task); }); } return *this; } //////////////////////////////////////////////////////////////////////////////// -void tc::Task::to_mut (TCReplica *replica) -{ - tc_task_to_mut(&*inner, replica); -} +void tc::Task::to_mut(TCReplica* replica) { tc_task_to_mut(&*inner, replica); } //////////////////////////////////////////////////////////////////////////////// -void tc::Task::to_immut () -{ - tc_task_to_immut(&*inner); -} +void tc::Task::to_immut() { tc_task_to_immut(&*inner); } //////////////////////////////////////////////////////////////////////////////// -std::string tc::Task::get_uuid () const -{ +std::string tc::Task::get_uuid() const { auto uuid = tc_task_get_uuid(&*inner); return tc2uuid(uuid); } //////////////////////////////////////////////////////////////////////////////// -tc::Status tc::Task::get_status () const -{ +tc::Status tc::Task::get_status() const { auto status = tc_task_get_status(&*inner); return tc::Status(status); } //////////////////////////////////////////////////////////////////////////////// -std::map tc::Task::get_taskmap () const -{ - TCKVList kv = tc_task_get_taskmap (&*inner); +std::map tc::Task::get_taskmap() const { + TCKVList kv = tc_task_get_taskmap(&*inner); if (!kv.items) { - throw task_error (); + throw task_error(); } std::map taskmap; @@ -107,89 +90,72 @@ std::map tc::Task::get_taskmap () const } //////////////////////////////////////////////////////////////////////////////// -std::string tc::Task::get_description () const -{ +std::string tc::Task::get_description() const { auto desc = tc_task_get_description(&*inner); return tc2string(desc); } //////////////////////////////////////////////////////////////////////////////// -std::optional tc::Task::get_value (std::string property) const -{ - auto maybe_desc = tc_task_get_value (&*inner, string2tc(property)); +std::optional tc::Task::get_value(std::string property) const { + auto maybe_desc = tc_task_get_value(&*inner, string2tc(property)); if (maybe_desc.ptr == NULL) { return std::nullopt; } return std::make_optional(tc2string(maybe_desc)); } -bool tc::Task::is_waiting () const -{ - return tc_task_is_waiting (&*inner); -} +bool tc::Task::is_waiting() const { return tc_task_is_waiting(&*inner); } //////////////////////////////////////////////////////////////////////////////// -bool tc::Task::is_active () const -{ - return tc_task_is_active (&*inner); -} +bool tc::Task::is_active() const { return tc_task_is_active(&*inner); } //////////////////////////////////////////////////////////////////////////////// -bool tc::Task::is_blocked () const -{ - return tc_task_is_blocked (&*inner); -} +bool tc::Task::is_blocked() const { return tc_task_is_blocked(&*inner); } //////////////////////////////////////////////////////////////////////////////// -bool tc::Task::is_blocking () const -{ - return tc_task_is_blocking (&*inner); -} +bool tc::Task::is_blocking() const { return tc_task_is_blocking(&*inner); } //////////////////////////////////////////////////////////////////////////////// -void tc::Task::set_status (tc::Status status) -{ - TCResult res = tc_task_set_status (&*inner, (TCStatus)status); +void tc::Task::set_status(tc::Status status) { + TCResult res = tc_task_set_status(&*inner, (TCStatus)status); if (res != TC_RESULT_OK) { - throw task_error (); + throw task_error(); } } //////////////////////////////////////////////////////////////////////////////// -void tc::Task::set_value (std::string property, std::optional value) -{ +void tc::Task::set_value(std::string property, std::optional value) { TCResult res; if (value.has_value()) { - res = tc_task_set_value (&*inner, string2tc(property), string2tc(value.value())); + res = tc_task_set_value(&*inner, string2tc(property), string2tc(value.value())); } else { TCString nullstr; nullstr.ptr = NULL; - res = tc_task_set_value (&*inner, string2tc(property), nullstr); + res = tc_task_set_value(&*inner, string2tc(property), nullstr); } if (res != TC_RESULT_OK) { - throw task_error (); + throw task_error(); } } //////////////////////////////////////////////////////////////////////////////// -void tc::Task::set_modified (time_t modified) -{ - TCResult res = tc_task_set_modified (&*inner, modified); +void tc::Task::set_modified(time_t modified) { + TCResult res = tc_task_set_modified(&*inner, modified); if (res != TC_RESULT_OK) { - throw task_error (); + throw task_error(); } } //////////////////////////////////////////////////////////////////////////////// -std::string tc::Task::task_error () const { - TCString error = tc_task_error (&*inner); +std::string tc::Task::task_error() const { + TCString error = tc_task_error(&*inner); std::string errmsg; if (!error.ptr) { - errmsg = std::string ("Unknown TaskChampion error"); + errmsg = std::string("Unknown TaskChampion error"); } else { - errmsg = std::string (tc_string_content (&error)); + errmsg = std::string(tc_string_content(&error)); } - tc_string_free (&error); + tc_string_free(&error); return errmsg; } diff --git a/src/tc/Task.h b/src/tc/Task.h index 2710768d3..d087dc810 100644 --- a/src/tc/Task.h +++ b/src/tc/Task.h @@ -27,101 +27,101 @@ #ifndef INCLUDED_TC_TASK #define INCLUDED_TC_TASK -#include #include -#include #include +#include #include +#include + #include "tc/ffi.h" namespace tc { - class Replica; - class ReplicaGuard; +class Replica; +class ReplicaGuard; - enum Status { - Pending = tc::ffi::TC_STATUS_PENDING, - Completed = tc::ffi::TC_STATUS_COMPLETED, - Deleted = tc::ffi::TC_STATUS_DELETED, - Recurring = tc::ffi::TC_STATUS_RECURRING, - Unknown = tc::ffi::TC_STATUS_UNKNOWN, - }; +enum Status { + Pending = tc::ffi::TC_STATUS_PENDING, + Completed = tc::ffi::TC_STATUS_COMPLETED, + Deleted = tc::ffi::TC_STATUS_DELETED, + Recurring = tc::ffi::TC_STATUS_RECURRING, + Unknown = tc::ffi::TC_STATUS_UNKNOWN, +}; - // a unique_ptr to a TCReplica which will automatically free the value when - // it goes out of scope. - using unique_tctask_ptr = std::unique_ptr< - tc::ffi::TCTask, - std::function>; +// a unique_ptr to a TCReplica which will automatically free the value when +// it goes out of scope. +using unique_tctask_ptr = std::unique_ptr>; +// Task wraps the TCTask type, managing its memory, errors, and so on. +// +// Except as noted, method names match the suffix to `tc_task_..`. +class Task { + protected: + // Tasks may only be created and made mutable/immutable + // by tc::Replica + friend class tc::Replica; + explicit Task(tc::ffi::TCTask *); - // Task wraps the TCTask type, managing its memory, errors, and so on. - // - // Except as noted, method names match the suffix to `tc_task_..`. - class Task - { - protected: - // Tasks may only be created and made mutable/immutable - // by tc::Replica - friend class tc::Replica; - explicit Task (tc::ffi::TCTask *); + // RplicaGuard handles mut/immut + friend class tc::ReplicaGuard; + void to_mut(tc::ffi::TCReplica *); + void to_immut(); - // RplicaGuard handles mut/immut - friend class tc::ReplicaGuard; - void to_mut(tc::ffi::TCReplica *); - void to_immut(); + public: + // This object "owns" inner, so copy is not allowed. + Task(const Task &) = delete; + Task &operator=(const Task &) = delete; - public: - // This object "owns" inner, so copy is not allowed. - Task (const Task &) = delete; - Task &operator=(const Task &) = delete; + // Explicit move constructor and assignment + Task(Task &&) noexcept; + Task &operator=(Task &&) noexcept; - // Explicit move constructor and assignment - Task (Task &&) noexcept; - Task &operator=(Task &&) noexcept; + std::string get_uuid() const; + Status get_status() const; + std::map get_taskmap() const; + std::string get_description() const; + std::optional get_value(std::string property) const; + // TODO: time_t tc_task_get_entry(struct TCTask *task); + // TODO: time_t tc_task_get_wait(struct TCTask *task); + // TODO: time_t tc_task_get_modified(struct TCTask *task); + bool is_waiting() const; + bool is_active() const; + bool is_blocked() const; + bool is_blocking() const; + // TODO: bool tc_task_has_tag(struct TCTask *task, struct TCString tag); + // TODO: struct TCStringList tc_task_get_tags(struct TCTask *task); + // TODO: struct TCAnnotationList tc_task_get_annotations(struct TCTask *task); + // TODO: struct TCString tc_task_get_uda(struct TCTask *task, struct TCString ns, struct TCString + // key); + // TODO: struct TCString tc_task_get_legacy_uda(struct TCTask *task, struct TCString key); + // TODO: struct TCUdaList tc_task_get_udas(struct TCTask *task); + // TODO: struct TCUdaList tc_task_get_legacy_udas(struct TCTask *task); + void set_status(Status status); + // TODO: TCResult tc_task_set_description(struct TCTask *task, struct TCString description); + void set_value(std::string property, std::optional value); + // TODO: TCResult tc_task_set_entry(struct TCTask *task, time_t entry); + // TODO: TCResult tc_task_set_wait(struct TCTask *task, time_t wait); + void set_modified(time_t modified); + // TODO: TCResult tc_task_start(struct TCTask *task); + // TODO: TCResult tc_task_stop(struct TCTask *task); + // TODO: TCResult tc_task_done(struct TCTask *task); + // TODO: TCResult tc_task_delete(struct TCTask *task); + // TODO: TCResult tc_task_add_tag(struct TCTask *task, struct TCString tag); + // TODO: TCResult tc_task_remove_tag(struct TCTask *task, struct TCString tag); + // TODO: TCResult tc_task_add_annotation(struct TCTask *task, struct TCAnnotation *annotation); + // TODO: TCResult tc_task_remove_annotation(struct TCTask *task, int64_t entry); + // TODO: TCResult tc_task_set_uda(struct TCTask *task, + // TODO: TCResult tc_task_remove_uda(struct TCTask *task, struct TCString ns, struct TCString + // key); + // TODO: TCResult tc_task_set_legacy_uda(struct TCTask *task, struct TCString key, struct TCString + // value); + // TODO: TCResult tc_task_remove_legacy_uda(struct TCTask *task, struct TCString key); - std::string get_uuid () const; - Status get_status () const; - std::map get_taskmap() const; - std::string get_description() const; - std::optional get_value(std::string property) const; -// TODO: time_t tc_task_get_entry(struct TCTask *task); -// TODO: time_t tc_task_get_wait(struct TCTask *task); -// TODO: time_t tc_task_get_modified(struct TCTask *task); - bool is_waiting() const; - bool is_active() const; - bool is_blocked() const; - bool is_blocking() const; -// TODO: bool tc_task_has_tag(struct TCTask *task, struct TCString tag); -// TODO: struct TCStringList tc_task_get_tags(struct TCTask *task); -// TODO: struct TCAnnotationList tc_task_get_annotations(struct TCTask *task); -// TODO: struct TCString tc_task_get_uda(struct TCTask *task, struct TCString ns, struct TCString key); -// TODO: struct TCString tc_task_get_legacy_uda(struct TCTask *task, struct TCString key); -// TODO: struct TCUdaList tc_task_get_udas(struct TCTask *task); -// TODO: struct TCUdaList tc_task_get_legacy_udas(struct TCTask *task); - void set_status(Status status); -// TODO: TCResult tc_task_set_description(struct TCTask *task, struct TCString description); - void set_value(std::string property, std::optional value); -// TODO: TCResult tc_task_set_entry(struct TCTask *task, time_t entry); -// TODO: TCResult tc_task_set_wait(struct TCTask *task, time_t wait); - void set_modified(time_t modified); -// TODO: TCResult tc_task_start(struct TCTask *task); -// TODO: TCResult tc_task_stop(struct TCTask *task); -// TODO: TCResult tc_task_done(struct TCTask *task); -// TODO: TCResult tc_task_delete(struct TCTask *task); -// TODO: TCResult tc_task_add_tag(struct TCTask *task, struct TCString tag); -// TODO: TCResult tc_task_remove_tag(struct TCTask *task, struct TCString tag); -// TODO: TCResult tc_task_add_annotation(struct TCTask *task, struct TCAnnotation *annotation); -// TODO: TCResult tc_task_remove_annotation(struct TCTask *task, int64_t entry); -// TODO: TCResult tc_task_set_uda(struct TCTask *task, -// TODO: TCResult tc_task_remove_uda(struct TCTask *task, struct TCString ns, struct TCString key); -// TODO: TCResult tc_task_set_legacy_uda(struct TCTask *task, struct TCString key, struct TCString value); -// TODO: TCResult tc_task_remove_legacy_uda(struct TCTask *task, struct TCString key); + private: + unique_tctask_ptr inner; - private: - unique_tctask_ptr inner; - - std::string task_error () const; // tc_task_error - }; -} + std::string task_error() const; // tc_task_error +}; +} // namespace tc // TODO: struct TCTask *tc_task_list_take(struct TCTaskList *tasks, size_t index); // TODO: void tc_task_list_free(struct TCTaskList *tasks); diff --git a/src/tc/WorkingSet.cpp b/src/tc/WorkingSet.cpp index b089f347c..1adeb8f9d 100644 --- a/src/tc/WorkingSet.cpp +++ b/src/tc/WorkingSet.cpp @@ -28,70 +28,57 @@ // cmake.h include header must come first #include -#include "tc/WorkingSet.h" + #include "tc/Task.h" +#include "tc/WorkingSet.h" #include "tc/util.h" using namespace tc::ffi; //////////////////////////////////////////////////////////////////////////////// -tc::WorkingSet::WorkingSet (WorkingSet &&other) noexcept -{ +tc::WorkingSet::WorkingSet(WorkingSet&& other) noexcept { // move inner from other - inner = unique_tcws_ptr ( - other.inner.release (), - [](TCWorkingSet* ws) { tc_working_set_free (ws); }); + inner = unique_tcws_ptr(other.inner.release(), [](TCWorkingSet* ws) { tc_working_set_free(ws); }); } //////////////////////////////////////////////////////////////////////////////// -tc::WorkingSet& tc::WorkingSet::operator= (WorkingSet &&other) noexcept -{ +tc::WorkingSet& tc::WorkingSet::operator=(WorkingSet&& other) noexcept { if (this != &other) { // move inner from other - inner = unique_tcws_ptr ( - other.inner.release (), - [](TCWorkingSet* ws) { tc_working_set_free (ws); }); + inner = + unique_tcws_ptr(other.inner.release(), [](TCWorkingSet* ws) { tc_working_set_free(ws); }); } return *this; } //////////////////////////////////////////////////////////////////////////////// -tc::WorkingSet::WorkingSet (tc::ffi::TCWorkingSet* tcws) -{ - inner = unique_tcws_ptr ( - tcws, - [](TCWorkingSet* ws) { tc_working_set_free (ws); }); +tc::WorkingSet::WorkingSet(tc::ffi::TCWorkingSet* tcws) { + inner = unique_tcws_ptr(tcws, [](TCWorkingSet* ws) { tc_working_set_free(ws); }); } //////////////////////////////////////////////////////////////////////////////// -size_t tc::WorkingSet::len () const noexcept -{ - return tc_working_set_len (&*inner); +size_t tc::WorkingSet::len() const noexcept { return tc_working_set_len(&*inner); } + +//////////////////////////////////////////////////////////////////////////////// +size_t tc::WorkingSet::largest_index() const noexcept { + return tc_working_set_largest_index(&*inner); } //////////////////////////////////////////////////////////////////////////////// -size_t tc::WorkingSet::largest_index () const noexcept -{ - return tc_working_set_largest_index (&*inner); -} - -//////////////////////////////////////////////////////////////////////////////// -std::optional tc::WorkingSet::by_index (size_t index) const noexcept -{ +std::optional tc::WorkingSet::by_index(size_t index) const noexcept { TCUuid uuid; - if (tc_working_set_by_index (&*inner, index, &uuid)) { - return std::make_optional (tc2uuid (uuid)); + if (tc_working_set_by_index(&*inner, index, &uuid)) { + return std::make_optional(tc2uuid(uuid)); } else { return std::nullopt; } } //////////////////////////////////////////////////////////////////////////////// -std::optional tc::WorkingSet::by_uuid (const std::string &uuid) const noexcept -{ - auto index = tc_working_set_by_uuid (&*inner, uuid2tc (uuid)); +std::optional tc::WorkingSet::by_uuid(const std::string& uuid) const noexcept { + auto index = tc_working_set_by_uuid(&*inner, uuid2tc(uuid)); if (index > 0) { - return std::make_optional (index); + return std::make_optional(index); } else { return std::nullopt; } diff --git a/src/tc/WorkingSet.h b/src/tc/WorkingSet.h index 7b6c63423..e9a3a5d5c 100644 --- a/src/tc/WorkingSet.h +++ b/src/tc/WorkingSet.h @@ -27,49 +27,48 @@ #ifndef INCLUDED_TC_WORKINGSET #define INCLUDED_TC_WORKINGSET -#include #include #include #include -#include "tc/ffi.h" +#include + #include "tc/Task.h" +#include "tc/ffi.h" namespace tc { - class Task; +class Task; - // a unique_ptr to a TCWorkingSet which will automatically free the value when - // it goes out of scope. - using unique_tcws_ptr = std::unique_ptr< - tc::ffi::TCWorkingSet, - std::function>; +// a unique_ptr to a TCWorkingSet which will automatically free the value when +// it goes out of scope. +using unique_tcws_ptr = + std::unique_ptr>; - // WorkingSet wraps the TCWorkingSet type, managing its memory, errors, and so on. - // - // Except as noted, method names match the suffix to `tc_working_set_..`. - class WorkingSet - { - protected: - friend class tc::Replica; - WorkingSet (tc::ffi::TCWorkingSet*); // via tc_replica_working_set +// WorkingSet wraps the TCWorkingSet type, managing its memory, errors, and so on. +// +// Except as noted, method names match the suffix to `tc_working_set_..`. +class WorkingSet { + protected: + friend class tc::Replica; + WorkingSet(tc::ffi::TCWorkingSet *); // via tc_replica_working_set - public: - // This object "owns" inner, so copy is not allowed. - WorkingSet (const WorkingSet &) = delete; - WorkingSet &operator=(const WorkingSet &) = delete; + public: + // This object "owns" inner, so copy is not allowed. + WorkingSet(const WorkingSet &) = delete; + WorkingSet &operator=(const WorkingSet &) = delete; - // Explicit move constructor and assignment - WorkingSet (WorkingSet &&) noexcept; - WorkingSet &operator=(WorkingSet &&) noexcept; + // Explicit move constructor and assignment + WorkingSet(WorkingSet &&) noexcept; + WorkingSet &operator=(WorkingSet &&) noexcept; - size_t len () const noexcept; // tc_working_set_len - size_t largest_index () const noexcept; // tc_working_set_largest_index - std::optional by_index (size_t index) const noexcept; // tc_working_set_by_index - std::optional by_uuid (const std::string &index) const noexcept; // tc_working_set_by_uuid + size_t len() const noexcept; // tc_working_set_len + size_t largest_index() const noexcept; // tc_working_set_largest_index + std::optional by_index(size_t index) const noexcept; // tc_working_set_by_index + std::optional by_uuid(const std::string &index) const noexcept; // tc_working_set_by_uuid - private: - unique_tcws_ptr inner; - }; -} + private: + unique_tcws_ptr inner; +}; +} // namespace tc #endif //////////////////////////////////////////////////////////////////////////////// diff --git a/src/tc/lib/taskchampion.h b/src/tc/lib/taskchampion.h index f0571d469..3d0cf5e9a 100644 --- a/src/tc/lib/taskchampion.h +++ b/src/tc/lib/taskchampion.h @@ -77,7 +77,7 @@ #define EXTERN_C extern "C" #else #define EXTERN_C -#endif // __cplusplus +#endif // __cplusplus // ***** TCResult ***** // @@ -85,15 +85,15 @@ // the associated object's `tc_.._error` method will return an error message. enum TCResult #ifdef __cplusplus - : int32_t -#endif // __cplusplus + : int32_t +#endif // __cplusplus { TC_RESULT_ERROR = -1, TC_RESULT_OK = 0, }; #ifndef __cplusplus typedef int32_t TCResult; -#endif // __cplusplus +#endif // __cplusplus // ***** TCString ***** // @@ -135,10 +135,10 @@ typedef int32_t TCResult; // // TCString is not threadsafe. typedef struct TCString { - void *ptr; // opaque, but may be checked for NULL - size_t _u1; // reserved - size_t _u2; // reserved - uint8_t _u3; // reserved + void *ptr; // opaque, but may be checked for NULL + size_t _u1; // reserved + size_t _u2; // reserved + uint8_t _u3; // reserved } TCString; // Create a new TCString referencing the given C string. The C string must remain valid and @@ -214,8 +214,8 @@ typedef struct TCStringList { struct TCString *items; } TCStringList; -// Free a TCStringList instance. The instance, and all TCStringList it contains, must not be used after -// this call. +// Free a TCStringList instance. The instance, and all TCStringList it contains, must not be used +// after this call. // // When this call returns, the `items` pointer will be NULL, signalling an invalid TCStringList. EXTERN_C void tc_string_list_free(struct TCStringList *tcstrings); @@ -310,8 +310,8 @@ typedef struct TCAnnotationList { struct TCAnnotation *items; } TCAnnotationList; -// Free a TCAnnotationList instance. The instance, and all TCAnnotations it contains, must not be used after -// this call. +// Free a TCAnnotationList instance. The instance, and all TCAnnotations it contains, must not be +// used after this call. // // When this call returns, the `items` pointer will be NULL, signalling an invalid TCAnnotationList. EXTERN_C void tc_annotation_list_free(struct TCAnnotationList *tcanns); @@ -390,10 +390,10 @@ EXTERN_C void tc_kv_list_free(struct TCKVList *tckvs); // The status of a task, as defined by the task data model. #ifdef __cplusplus typedef enum TCStatus : int32_t { -#else // __cplusplus +#else // __cplusplus typedef int32_t TCStatus; enum TCStatus { -#endif // __cplusplus +#endif // __cplusplus TC_STATUS_PENDING = 0, TC_STATUS_COMPLETED = 1, TC_STATUS_DELETED = 2, @@ -403,9 +403,9 @@ enum TCStatus { TC_STATUS_UNKNOWN = -1, #ifdef __cplusplus } TCStatus; -#else // __cplusplus +#else // __cplusplus }; -#endif // __cplusplus +#endif // __cplusplus // ***** TCServer ***** // @@ -424,7 +424,8 @@ typedef struct TCServer TCServer; // returned. The caller must free this string. // // The server must be freed after it is used - tc_replica_sync does not automatically free it. -EXTERN_C struct TCServer *tc_server_new_local(struct TCString server_dir, struct TCString *error_out); +EXTERN_C struct TCServer *tc_server_new_local(struct TCString server_dir, + struct TCString *error_out); // Create a new TCServer that connects to a remote server. See the TaskChampion docs for the // description of the arguments. @@ -433,10 +434,9 @@ EXTERN_C struct TCServer *tc_server_new_local(struct TCString server_dir, struct // returned. The caller must free this string. // // The server must be freed after it is used - tc_replica_sync does not automatically free it. -EXTERN_C struct TCServer *tc_server_new_sync(struct TCString url, - struct TCUuid client_id, - struct TCString encryption_secret, - struct TCString *error_out); +EXTERN_C struct TCServer *tc_server_new_sync(struct TCString url, struct TCUuid client_id, + struct TCString encryption_secret, + struct TCString *error_out); // Create a new TCServer that connects to the Google Cloud Platform. See the TaskChampion docs // for the description of the arguments. @@ -445,10 +445,9 @@ EXTERN_C struct TCServer *tc_server_new_sync(struct TCString url, // returned. The caller must free this string. // // The server must be freed after it is used - tc_replica_sync does not automatically free it. -EXTERN_C struct TCServer *tc_server_new_gcp(struct TCString bucket, - struct TCString credential_path, - struct TCString encryption_secret, - struct TCString *error_out); +EXTERN_C struct TCServer *tc_server_new_gcp(struct TCString bucket, struct TCString credential_path, + struct TCString encryption_secret, + struct TCString *error_out); // Free a server. The server may not be used after this function returns and must not be freed // more than once. @@ -483,31 +482,31 @@ typedef struct TCReplica TCReplica; // ***** TCReplicaOpType ***** enum TCReplicaOpType #ifdef __cplusplus - : uint32_t -#endif // __cplusplus + : uint32_t +#endif // __cplusplus { - Create = 0, - Delete = 1, - Update = 2, - UndoPoint = 3, + Create = 0, + Delete = 1, + Update = 2, + UndoPoint = 3, }; #ifndef __cplusplus typedef uint32_t TCReplicaOpType; -#endif // __cplusplus +#endif // __cplusplus // ***** TCReplicaOp ***** struct TCReplicaOp { - TCReplicaOpType operation_type; - void* inner; + TCReplicaOpType operation_type; + void *inner; }; typedef struct TCReplicaOp TCReplicaOp; // ***** TCReplicaOpList ***** struct TCReplicaOpList { - struct TCReplicaOp *items; - size_t len; - size_t capacity; + struct TCReplicaOp *items; + size_t len; + size_t capacity; }; typedef struct TCReplicaOpList TCReplicaOpList; @@ -519,9 +518,8 @@ EXTERN_C struct TCReplica *tc_replica_new_in_memory(void); // Create a new TCReplica with an on-disk database having the given filename. On error, a string // is written to the error_out parameter (if it is not NULL) and NULL is returned. The caller // must free this string. -EXTERN_C struct TCReplica *tc_replica_new_on_disk(struct TCString path, - bool create_if_missing, - struct TCString *error_out); +EXTERN_C struct TCReplica *tc_replica_new_on_disk(struct TCString path, bool create_if_missing, + struct TCString *error_out); // Add an UndoPoint, if one has not already been added by this Replica. This occurs automatically // when a change is made. The `force` flag allows forcing a new UndoPoint even if one has already @@ -545,7 +543,8 @@ EXTERN_C struct TCTaskList tc_replica_all_tasks(struct TCReplica *rep); // // If undone_out is not NULL, then on success it is set to 1 if operations were undone, or 0 if // there are no operations that can be done. -EXTERN_C TCResult tc_replica_commit_undo_ops(struct TCReplica *rep, TCReplicaOpList tc_undo_ops, int32_t *undone_out); +EXTERN_C TCResult tc_replica_commit_undo_ops(struct TCReplica *rep, TCReplicaOpList tc_undo_ops, + int32_t *undone_out); // Delete a task. The task must exist. Note that this is different from setting status to // Deleted; this is the final purge of the task. @@ -582,14 +581,14 @@ EXTERN_C TCReplicaOpList tc_replica_get_undo_ops(struct TCReplica *rep); // Create a new task. The task must not already exist. // // Returns the task, or NULL on error. -EXTERN_C struct TCTask *tc_replica_import_task_with_uuid(struct TCReplica *rep, struct TCUuid tcuuid); +EXTERN_C struct TCTask *tc_replica_import_task_with_uuid(struct TCReplica *rep, + struct TCUuid tcuuid); // Create a new task. The task must not already exist. // // Returns the task, or NULL on error. -EXTERN_C struct TCTask *tc_replica_new_task(struct TCReplica *rep, - enum TCStatus status, - struct TCString description); +EXTERN_C struct TCTask *tc_replica_new_task(struct TCReplica *rep, enum TCStatus status, + struct TCString description); // Get the number of local, un-synchronized operations (not including undo points), or -1 on // error. @@ -606,7 +605,8 @@ EXTERN_C TCResult tc_replica_rebuild_working_set(struct TCReplica *rep, bool ren // Synchronize this replica with a server. // // The `server` argument remains owned by the caller, and must be freed explicitly. -EXTERN_C TCResult tc_replica_sync(struct TCReplica *rep, struct TCServer *server, bool avoid_snapshots); +EXTERN_C TCResult tc_replica_sync(struct TCReplica *rep, struct TCServer *server, + bool avoid_snapshots); // Get the current working set for this replica. The resulting value must be freed // with tc_working_set_free. @@ -636,8 +636,8 @@ EXTERN_C struct TCString tc_replica_op_get_uuid(struct TCReplicaOp *op); // Return value field of ReplicaOp. EXTERN_C struct TCString tc_replica_op_get_value(struct TCReplicaOp *op); -// Free a vector of ReplicaOp. The vector may not be used after this function returns and must not be freed -// more than once. +// Free a vector of ReplicaOp. The vector may not be used after this function returns and must not +// be freed more than once. EXTERN_C void tc_replica_op_list_free(struct TCReplicaOpList *oplist); // ***** TCTask ***** @@ -719,7 +719,8 @@ EXTERN_C struct TCKVList tc_task_get_taskmap(struct TCTask *task); // Get the named UDA from the task. // // Returns a TCString with NULL ptr field if the UDA does not exist. -EXTERN_C struct TCString tc_task_get_uda(struct TCTask *task, struct TCString ns, struct TCString key); +EXTERN_C struct TCString tc_task_get_uda(struct TCTask *task, struct TCString ns, + struct TCString key); // Get all UDAs for this task. // @@ -809,7 +810,8 @@ EXTERN_C TCResult tc_task_set_description(struct TCTask *task, struct TCString d EXTERN_C TCResult tc_task_set_entry(struct TCTask *task, time_t entry); // Set a legacy UDA on a mutable task. -EXTERN_C TCResult tc_task_set_legacy_uda(struct TCTask *task, struct TCString key, struct TCString value); +EXTERN_C TCResult tc_task_set_legacy_uda(struct TCTask *task, struct TCString key, + struct TCString value); // Set a mutable task's modified timestamp. The value cannot be zero. EXTERN_C TCResult tc_task_set_modified(struct TCTask *task, time_t modified); @@ -818,13 +820,12 @@ EXTERN_C TCResult tc_task_set_modified(struct TCTask *task, time_t modified); EXTERN_C TCResult tc_task_set_status(struct TCTask *task, enum TCStatus status); // Set a UDA on a mutable task. -EXTERN_C TCResult tc_task_set_uda(struct TCTask *task, - struct TCString ns, - struct TCString key, - struct TCString value); +EXTERN_C TCResult tc_task_set_uda(struct TCTask *task, struct TCString ns, struct TCString key, + struct TCString value); // Set a mutable task's property value by name. If value.ptr is NULL, the property is removed. -EXTERN_C TCResult tc_task_set_value(struct TCTask *task, struct TCString property, struct TCString value); +EXTERN_C TCResult tc_task_set_value(struct TCTask *task, struct TCString property, + struct TCString value); // Set a mutable task's wait timestamp. Pass wait=0 to unset the wait field. EXTERN_C TCResult tc_task_set_wait(struct TCTask *task, time_t wait); @@ -916,7 +917,8 @@ typedef struct TCWorkingSet TCWorkingSet; // Get the UUID for the task at the given index. Returns true if the UUID exists in the working // set. If not, returns false and does not change uuid_out. -EXTERN_C bool tc_working_set_by_index(struct TCWorkingSet *ws, size_t index, struct TCUuid *uuid_out); +EXTERN_C bool tc_working_set_by_index(struct TCWorkingSet *ws, size_t index, + struct TCUuid *uuid_out); // Get the working set index for the task with the given UUID. Returns 0 if the task is not in // the working set. diff --git a/src/tc/util.cpp b/src/tc/util.cpp index 318f9ed0f..3339615ce 100644 --- a/src/tc/util.cpp +++ b/src/tc/util.cpp @@ -27,8 +27,9 @@ #include // cmake.h include header must come first -#include #include +#include + #include "tc/Replica.h" #include "tc/Task.h" @@ -36,48 +37,43 @@ using namespace tc::ffi; namespace tc { //////////////////////////////////////////////////////////////////////////////// -TCString string2tc (const std::string& str) -{ - return tc_string_clone_with_len (str.data (), str.size ()); +TCString string2tc(const std::string& str) { + return tc_string_clone_with_len(str.data(), str.size()); } //////////////////////////////////////////////////////////////////////////////// -std::string tc2string_clone (const TCString& str) -{ +std::string tc2string_clone(const TCString& str) { size_t len; - auto ptr = tc_string_content_with_len (&str, &len); - auto rv = std::string (ptr, len); + auto ptr = tc_string_content_with_len(&str, &len); + auto rv = std::string(ptr, len); return rv; } //////////////////////////////////////////////////////////////////////////////// -std::string tc2string (TCString& str) -{ +std::string tc2string(TCString& str) { auto rv = tc2string_clone(str); - tc_string_free (&str); + tc_string_free(&str); return rv; } //////////////////////////////////////////////////////////////////////////////// -TCUuid uuid2tc(const std::string& str) -{ +TCUuid uuid2tc(const std::string& str) { TCString tcstr = tc_string_borrow(str.c_str()); TCUuid rv; if (TC_RESULT_OK != tc_uuid_from_str(tcstr, &rv)) { - throw std::string ("invalid UUID"); + throw std::string("invalid UUID"); } return rv; } //////////////////////////////////////////////////////////////////////////////// -std::string tc2uuid (TCUuid& uuid) -{ +std::string tc2uuid(TCUuid& uuid) { char s[TC_UUID_STRING_BYTES]; - tc_uuid_to_buf (uuid, s); + tc_uuid_to_buf(uuid, s); std::string str; - str.assign (s, TC_UUID_STRING_BYTES); + str.assign(s, TC_UUID_STRING_BYTES); return str; } //////////////////////////////////////////////////////////////////////////////// -} +} // namespace tc diff --git a/src/tc/util.h b/src/tc/util.h index 66ca54b2e..87d54cd16 100644 --- a/src/tc/util.h +++ b/src/tc/util.h @@ -28,24 +28,25 @@ #define INCLUDED_TC_UTIL #include + #include "tc/ffi.h" namespace tc { - // convert a std::string into a TCString, copying the contained data - tc::ffi::TCString string2tc(const std::string&); +// convert a std::string into a TCString, copying the contained data +tc::ffi::TCString string2tc(const std::string&); - // convert a TCString into a std::string, leaving the TCString as-is - std::string tc2string_clone(const tc::ffi::TCString&); +// convert a TCString into a std::string, leaving the TCString as-is +std::string tc2string_clone(const tc::ffi::TCString&); - // convert a TCString into a std::string, freeing the TCString - std::string tc2string(tc::ffi::TCString&); +// convert a TCString into a std::string, freeing the TCString +std::string tc2string(tc::ffi::TCString&); - // convert a TCUuid into a std::string - std::string tc2uuid(tc::ffi::TCUuid&); +// convert a TCUuid into a std::string +std::string tc2uuid(tc::ffi::TCUuid&); - // parse a std::string into a TCUuid (throwing if parse fails) - tc::ffi::TCUuid uuid2tc(const std::string&); -} +// parse a std::string into a TCUuid (throwing if parse fails) +tc::ffi::TCUuid uuid2tc(const std::string&); +} // namespace tc #endif //////////////////////////////////////////////////////////////////////////////// diff --git a/src/util.cpp b/src/util.cpp index da6eb4f93..04593791f 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -34,48 +34,46 @@ #ifdef FREEBSD #define _WITH_GETLINE #endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include #include #include +#include +#include +#include +#include #include -#include +#include +#include +#include #include +#include #include #include -#include -#define STRING_UTIL_CONFIRM_YES "yes" -#define STRING_UTIL_CONFIRM_YES_U "Yes" -#define STRING_UTIL_CONFIRM_NO "no" -#define STRING_UTIL_CONFIRM_ALL "all" -#define STRING_UTIL_CONFIRM_ALL_U "All" -#define STRING_UTIL_CONFIRM_QUIT "quit" +#include +#include +#include +#include +#include +#include +#include + +#define STRING_UTIL_CONFIRM_YES "yes" +#define STRING_UTIL_CONFIRM_YES_U "Yes" +#define STRING_UTIL_CONFIRM_NO "no" +#define STRING_UTIL_CONFIRM_ALL "all" +#define STRING_UTIL_CONFIRM_ALL_U "All" +#define STRING_UTIL_CONFIRM_QUIT "quit" static const char* newline = "\n"; -static const char* noline = ""; +static const char* noline = ""; //////////////////////////////////////////////////////////////////////////////// -static void signal_handler (int s) -{ - if (s == SIGINT) - { +static void signal_handler(int s) { + if (s == SIGINT) { std::cout << "\n\nInterrupted: No changes made.\n"; - exit (1); + exit(1); } } @@ -84,45 +82,38 @@ static void signal_handler (int s) // 1 = yes // 2 = all // 3 = quit -int confirm4 (const std::string& question) -{ - std::vector options {STRING_UTIL_CONFIRM_YES_U, - STRING_UTIL_CONFIRM_YES, - STRING_UTIL_CONFIRM_NO, - STRING_UTIL_CONFIRM_ALL_U, - STRING_UTIL_CONFIRM_ALL, - STRING_UTIL_CONFIRM_QUIT}; - std::vector matches; +int confirm4(const std::string& question) { + std::vector options{STRING_UTIL_CONFIRM_YES_U, STRING_UTIL_CONFIRM_YES, + STRING_UTIL_CONFIRM_NO, STRING_UTIL_CONFIRM_ALL_U, + STRING_UTIL_CONFIRM_ALL, STRING_UTIL_CONFIRM_QUIT}; + std::vector matches; - signal (SIGINT, signal_handler); + signal(SIGINT, signal_handler); - do - { - std::cout << question - << " (" - << options[1] << '/' - << options[2] << '/' - << options[4] << '/' - << options[5] - << ") "; + do { + std::cout << question << " (" << options[1] << '/' << options[2] << '/' << options[4] << '/' + << options[5] << ") "; - std::string answer {""}; - std::getline (std::cin, answer); - Context::getContext ().debug ("STDIN '" + answer + '\''); - answer = std::cin.eof () ? STRING_UTIL_CONFIRM_QUIT : Lexer::lowerCase (Lexer::trim (answer)); - autoComplete (answer, options, matches, 1); // Hard-coded 1. - } - while (! std::cin.eof () && matches.size () != 1); + std::string answer{""}; + std::getline(std::cin, answer); + Context::getContext().debug("STDIN '" + answer + '\''); + answer = std::cin.eof() ? STRING_UTIL_CONFIRM_QUIT : Lexer::lowerCase(Lexer::trim(answer)); + autoComplete(answer, options, matches, 1); // Hard-coded 1. + } while (!std::cin.eof() && matches.size() != 1); - signal (SIGINT, SIG_DFL); + signal(SIGINT, SIG_DFL); - if (matches.size () == 1) - { - if (matches[0] == STRING_UTIL_CONFIRM_YES_U) return 1; - else if (matches[0] == STRING_UTIL_CONFIRM_YES) return 1; - else if (matches[0] == STRING_UTIL_CONFIRM_ALL_U) return 2; - else if (matches[0] == STRING_UTIL_CONFIRM_ALL) return 2; - else if (matches[0] == STRING_UTIL_CONFIRM_QUIT) return 3; + if (matches.size() == 1) { + if (matches[0] == STRING_UTIL_CONFIRM_YES_U) + return 1; + else if (matches[0] == STRING_UTIL_CONFIRM_YES) + return 1; + else if (matches[0] == STRING_UTIL_CONFIRM_ALL_U) + return 2; + else if (matches[0] == STRING_UTIL_CONFIRM_ALL) + return 2; + else if (matches[0] == STRING_UTIL_CONFIRM_QUIT) + return 3; } return 0; @@ -135,16 +126,15 @@ int confirm4 (const std::string& question) // For the implementation details, refer to // https://svnweb.freebsd.org/base/head/sys/kern/kern_uuid.c #if defined(FREEBSD) || defined(OPENBSD) -const std::string uuid () -{ +const std::string uuid() { uuid_t id; uint32_t status; - char *buffer (0); - uuid_create (&id, &status); - uuid_to_string (&id, &buffer, &status); + char* buffer(0); + uuid_create(&id, &status); + uuid_to_string(&id, &buffer, &status); - std::string res (buffer); - free (buffer); + std::string res(buffer); + free(buffer); return res; } @@ -153,26 +143,24 @@ const std::string uuid () //////////////////////////////////////////////////////////////////////////////// #ifndef HAVE_UUID_UNPARSE_LOWER // Older versions of libuuid don't have uuid_unparse_lower(), only uuid_unparse() -void uuid_unparse_lower (uuid_t uu, char *out) -{ - uuid_unparse (uu, out); - // Characters in out are either 0-9, a-z, '-', or A-Z. A-Z is mapped to - // a-z by bitwise or with 0x20, and the others already have this bit set - for (size_t i = 0; i < 36; ++i) out[i] |= 0x20; +void uuid_unparse_lower(uuid_t uu, char* out) { + uuid_unparse(uu, out); + // Characters in out are either 0-9, a-z, '-', or A-Z. A-Z is mapped to + // a-z by bitwise or with 0x20, and the others already have this bit set + for (size_t i = 0; i < 36; ++i) out[i] |= 0x20; } #endif -const std::string uuid () -{ +const std::string uuid() { uuid_t id; - uuid_generate (id); - char buffer[100] {}; - uuid_unparse_lower (id, buffer); + uuid_generate(id); + char buffer[100]{}; + uuid_unparse_lower(id, buffer); // Bug found by Steven de Brouwer. buffer[36] = '\0'; - return std::string (buffer); + return std::string(buffer); } #endif @@ -201,19 +189,15 @@ const std::string uuid () // - delimiter is the character used to split up projects into subprojects. // - defaults to the period, '.' // -const std::string indentProject ( - const std::string& project, - const std::string& whitespace /* = " " */, - char delimiter /* = '.' */) -{ +const std::string indentProject(const std::string& project, + const std::string& whitespace /* = " " */, + char delimiter /* = '.' */) { // Count the delimiters in *i. std::string prefix = ""; std::string::size_type pos = 0; std::string::size_type lastpos = 0; - while ((pos = project.find (delimiter, pos + 1)) != std::string::npos) - { - if (pos != project.size () - 1) - { + while ((pos = project.find(delimiter, pos + 1)) != std::string::npos) { + if (pos != project.size() - 1) { prefix += whitespace; lastpos = pos; } @@ -223,23 +207,19 @@ const std::string indentProject ( if (lastpos == 0) child = project; else - child = project.substr (lastpos + 1); + child = project.substr(lastpos + 1); return prefix + child; } //////////////////////////////////////////////////////////////////////////////// -const std::vector extractParents ( - const std::string& project, - const char& delimiter /* = '.' */) -{ - std::vector vec; +const std::vector extractParents(const std::string& project, + const char& delimiter /* = '.' */) { + std::vector vec; std::string::size_type pos = 0; std::string::size_type copyUntil = 0; - while ((copyUntil = project.find (delimiter, pos + 1)) != std::string::npos) - { - if (copyUntil != project.size () - 1) - vec.push_back (project.substr (0, copyUntil)); + while ((copyUntil = project.find(delimiter, pos + 1)) != std::string::npos) { + if (copyUntil != project.size() - 1) vec.push_back(project.substr(0, copyUntil)); pos = copyUntil; } return vec; @@ -247,75 +227,63 @@ const std::vector extractParents ( //////////////////////////////////////////////////////////////////////////////// #ifndef HAVE_TIMEGM -time_t timegm (struct tm *tm) -{ +time_t timegm(struct tm* tm) { time_t ret; - char *tz; - tz = getenv ("TZ"); - setenv ("TZ", "UTC", 1); - tzset (); - ret = mktime (tm); + char* tz; + tz = getenv("TZ"); + setenv("TZ", "UTC", 1); + tzset(); + ret = mktime(tm); if (tz) - setenv ("TZ", tz, 1); + setenv("TZ", tz, 1); else - unsetenv ("TZ"); - tzset (); + unsetenv("TZ"); + tzset(); return ret; } #endif //////////////////////////////////////////////////////////////////////////////// -bool nontrivial (const std::string& input) -{ +bool nontrivial(const std::string& input) { std::string::size_type i = 0; int character; - while ((character = utf8_next_char (input, i))) - if (! unicodeWhitespace (character)) - return true; + while ((character = utf8_next_char(input, i))) + if (!unicodeWhitespace(character)) return true; return false; } //////////////////////////////////////////////////////////////////////////////// -const char* optionalBlankLine () -{ - return Context::getContext ().verbose ("blank") ? newline : noline; +const char* optionalBlankLine() { + return Context::getContext().verbose("blank") ? newline : noline; } //////////////////////////////////////////////////////////////////////////////// -void setHeaderUnderline (Table& table) -{ +void setHeaderUnderline(Table& table) { // If an alternating row color is specified, notify the table. - if (Context::getContext ().color ()) - { - Color alternate (Context::getContext ().config.get ("color.alternate")); - table.colorOdd (alternate); - table.intraColorOdd (alternate); + if (Context::getContext().color()) { + Color alternate(Context::getContext().config.get("color.alternate")); + table.colorOdd(alternate); + table.intraColorOdd(alternate); - if (Context::getContext ().config.getBoolean ("fontunderline")) - { - table.colorHeader (Color ("underline " + Context::getContext ().config.get ("color.label"))); + if (Context::getContext().config.getBoolean("fontunderline")) { + table.colorHeader(Color("underline " + Context::getContext().config.get("color.label"))); + } else { + table.colorHeader(Color(Context::getContext().config.get("color.label"))); + table.underlineHeaders(); } + } else { + if (Context::getContext().config.getBoolean("fontunderline")) + table.colorHeader(Color("underline")); else - { - table.colorHeader (Color (Context::getContext ().config.get ("color.label"))); - table.underlineHeaders (); - } - } - else - { - if (Context::getContext ().config.getBoolean ("fontunderline")) - table.colorHeader (Color ("underline")); - else - table.underlineHeaders (); + table.underlineHeaders(); } } //////////////////////////////////////////////////////////////////////////////// // Perform strtol on a string and check if the extracted value matches. // -bool extractLongInteger (const std::string& input, long& output) -{ - output = strtol (input.c_str (), nullptr, 10); - return (format ("{1}", output) == input); +bool extractLongInteger(const std::string& input, long& output) { + output = strtol(input.c_str(), nullptr, 10); + return (format("{1}", output) == input); } diff --git a/src/util.h b/src/util.h index 62e8223b0..a4f94a1a9 100644 --- a/src/util.h +++ b/src/util.h @@ -30,10 +30,11 @@ #include // cmake.h include header must come first +#include + +#include #include #include -#include -#include #if defined(FREEBSD) || defined(OPENBSD) #include #else @@ -42,30 +43,26 @@ #include // util.cpp -int confirm4 (const std::string&); +int confirm4(const std::string&); #ifndef HAVE_UUID_UNPARSE_LOWER -void uuid_unparse_lower (uuid_t uu, char *out); +void uuid_unparse_lower(uuid_t uu, char* out); #endif -const std::string uuid (); +const std::string uuid(); -const std::string indentProject ( - const std::string&, - const std::string& whitespace = " ", - char delimiter = '.'); +const std::string indentProject(const std::string&, const std::string& whitespace = " ", + char delimiter = '.'); -const std::vector extractParents ( - const std::string&, - const char& delimiter = '.'); +const std::vector extractParents(const std::string&, const char& delimiter = '.'); #ifndef HAVE_TIMEGM - time_t timegm (struct tm *tm); +time_t timegm(struct tm* tm); #endif -bool nontrivial (const std::string&); -const char* optionalBlankLine (); -void setHeaderUnderline (Table&); -bool extractLongInteger (const std::string&, long&); +bool nontrivial(const std::string&); +const char* optionalBlankLine(); +void setHeaderUnderline(Table&); +bool extractLongInteger(const std::string&, long&); #endif //////////////////////////////////////////////////////////////////////////////// diff --git a/test/README.md b/test/README.md index 6b19ec215..eafc2d956 100644 --- a/test/README.md +++ b/test/README.md @@ -139,4 +139,4 @@ For anyone looking for test-related tasks to take on, here are some suggestions: * All the attribute modifiers need to be tested, only a few are. - * Aliases are not well tested, and fragile. \ No newline at end of file + * Aliases are not well tested, and fragile. diff --git a/test/abbreviation.test.py b/test/abbreviation.test.py index f85c883fa..94b0c4577 100755 --- a/test/abbreviation.test.py +++ b/test/abbreviation.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -88,10 +89,11 @@ class TestAbbreviation(TestCase): class TestBug1006(TestCase): """Bug with expansion of abbreviation "des" in task descriptions and annotations. - It happens for all the shortcuts for column attributes that are automatically - completed. This is because DOM elements are checked before standard words - when strings are tokenized. + It happens for all the shortcuts for column attributes that are automatically + completed. This is because DOM elements are checked before standard words + when strings are tokenized. """ + def setUp(self): self.t = Task() self.t.config("verbose", "affected") @@ -158,6 +160,7 @@ class TestBug1687(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/add.test.py b/test/add.test.py index 60331b7a2..ac635c03d 100755 --- a/test/add.test.py +++ b/test/add.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -58,11 +59,11 @@ class TestAdd(TestCase): def test_floating_point_preservation(self): """924: Verify that floating point numbers are unmolested - Bug 924: '1.0' --> '1.0000' + Bug 924: '1.0' --> '1.0000' """ self.t("add release 1.0") self.t("add 'release 2.0'") - self.t("add \\\"release 3.0\\\"") + self.t('add \\"release 3.0\\"') code, out, err = self.t("_get 1.description") self.assertEqual(out, "release 1.0\n") @@ -76,19 +77,19 @@ class TestAdd(TestCase): def test_escaped_quotes_are_preserved(self): """917: Verify that escaped quotes are preserved - Bug 917: escaping runs amok + Bug 917: escaping runs amok """ self.t("add one \\'two\\' three") - self.t("add four \\\"five\\\" six") + self.t('add four \\"five\\" six') code, out, err = self.t("list") self.assertIn("one 'two' three", out) - self.assertIn("four \"five\" six", out) + self.assertIn('four "five" six', out) def test_extra_space_in_path(self): """884: Test that path-like args are preserved - Bug 884: Extra space in path name. + Bug 884: Extra space in path name. """ self.t("add /one/two/three/") self.t("add '/four/five/six/'") @@ -100,9 +101,9 @@ class TestAdd(TestCase): def test_parentheses_and_spaces_preserved(self): """819: Test parentheses and spacing is preserved on add - Bug 819: When I run "task add foo\'s bar." the description of the new task is "foo 's bar .". + Bug 819: When I run "task add foo\'s bar." the description of the new task is "foo 's bar .". """ - self.t("add foo\\\'s bar") + self.t("add foo\\'s bar") self.t("add foo (bar)") self.t("add 'baz (qux)'") @@ -114,11 +115,11 @@ class TestAdd(TestCase): def test_single_quote_preserved(self): """1642: Test single quote in a terminated multi-word string is preserved - TW-1642: After "--", an apostrophe unexpectedly ends the task description + TW-1642: After "--", an apostrophe unexpectedly ends the task description """ - self.t("add -- \"Return Randy's stuff\"") + self.t('add -- "Return Randy\'s stuff"') - code, out, err = self.t ("_get 1.description") + code, out, err = self.t("_get 1.description") self.assertIn("Return Randy's stuff\n", out) @@ -190,7 +191,7 @@ class Test1549(TestCase): """ # This command will hang and therefore timeout in 2.4.1. - code, out, err = self.t('rc.verbose:new-id add 1e x') + code, out, err = self.t("rc.verbose:new-id add 1e x") self.assertIn("Created task 1.", out) @@ -202,7 +203,7 @@ class TestBug1612(TestCase): def test_spurious_whitespace(self): """1612: ensure that extra whitespace does not get added. - tw-1612: Spurious whitespace added in task descriptions around certain symbols + tw-1612: Spurious whitespace added in task descriptions around certain symbols """ self.t("add 'foo-bar (http://baz.org/)'") self.t("add 'spam (foo bar)'") @@ -232,8 +233,8 @@ class TestBug1719(TestCase): def test_improper_ordinals(self): """1719: Description cannot contain improper ordinals""" - self.t("add one 1th"); - self.t("add two 23rd"); + self.t("add one 1th") + self.t("add two 23rd") code, out, err = self.t("_get 1.description") self.assertEqual("one 1th\n", out) @@ -244,6 +245,7 @@ class TestBug1719(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/alias.test.py b/test/alias.test.py index 816d978a0..f7cb4f918 100755 --- a/test/alias.test.py +++ b/test/alias.test.py @@ -29,6 +29,7 @@ import sys import os import unittest from datetime import datetime + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -55,28 +56,25 @@ class TestAlias(TestCase): # Sanity check that _projects command outputs the "Home" project code, out, err = self.t("_projects") - self.assertIn(expected, out, - msg="task _projects -> Home") + self.assertIn(expected, out, msg="task _projects -> Home") # Check that foo command outputs the "Home" project code, out, err = self.t("foo") - self.assertIn(expected, out, - msg="task foo -> _projects > Home") + self.assertIn(expected, out, msg="task foo -> _projects > Home") # Check that bar command outputs the "Home" project code, out, err = self.t("bar") - self.assertIn(expected, out, - msg="task bar -> foo > _projects > Home") + self.assertIn(expected, out, msg="task bar -> foo > _projects > Home") # Check that baz command outputs the "Home" project code, out, err = self.t("baz") - self.assertIn(expected, out, - msg="task baz -> bar > foo > _projects > Home") + self.assertIn(expected, out, msg="task baz -> bar > foo > _projects > Home") # Check that qux command outputs the "Home" project code, out, err = self.t("qux") - self.assertIn(expected, out, - msg="task qux -> baz > bar > foo > _projects > Home") + self.assertIn( + expected, out, msg="task qux -> baz > bar > foo > _projects > Home" + ) def test_alias_with_implicit_filter(self): """Test alias containing simple filter string""" @@ -91,17 +89,17 @@ class TestAlias(TestCase): # Sanity check that _projects command outputs # both the "Home" and "Work" projects code, out, err = self.t("_projects") - self.assertIn("Home", out, - msg="task _projects -> Home") - self.assertIn("Work", out, - msg="task _projects -> Work") + self.assertIn("Home", out, msg="task _projects -> Home") + self.assertIn("Work", out, msg="task _projects -> Work") # Check that foo command outputs the "Home" project code, out, err = self.t("foofilter") - self.assertIn("Home", out, - msg="task foofilter -> project:Home _projects > Home") - self.assertNotIn("Work", out, - msg="task foofilter -> project:Home _projects > Work") + self.assertIn( + "Home", out, msg="task foofilter -> project:Home _projects > Home" + ) + self.assertNotIn( + "Work", out, msg="task foofilter -> project:Home _projects > Work" + ) def test_alias_with_implicit_complex_filter(self): """Test alias containing filter string with conjuction""" @@ -116,20 +114,28 @@ class TestAlias(TestCase): # Check that hometoday command outputs the "Home urgent task" code, out, err = self.t("hometoday") - self.assertIn("Home urgent task", out, - msg="task hometoday -> project:Home and due:today minimal > " - "Home urgent task") + self.assertIn( + "Home urgent task", + out, + msg="task hometoday -> project:Home and due:today minimal > " + "Home urgent task", + ) # It should not output "Home task", as that one is not due:today - self.assertNotIn("Home task", out, - msg="task hometoday -> project:Home and due:today minimal > " - "Home task") + self.assertNotIn( + "Home task", + out, + msg="task hometoday -> project:Home and due:today minimal > " "Home task", + ) # It should not output "Work task" either, it has entirely wrong # project - self.assertNotIn("Work task", out, - msg="task hometoday -> project:Home and due:today minimal > " - "Work task") + self.assertNotIn( + "Work task", + out, + msg="task hometoday -> project:Home and due:today minimal > " "Work task", + ) + class TestAliasesCommand(TestCase): def setUp(self): @@ -142,6 +148,7 @@ class TestAliasesCommand(TestCase): code, out, err = self.t("_aliases") self.assertIn("foo", out) + class TestBug1652(TestCase): def setUp(self): """Executed before each test in the class""" @@ -156,6 +163,7 @@ class TestBug1652(TestCase): self.assertIn("Deleted 1 task.", out) self.assertNotIn("No matches.", err) + class TestBug1031(TestCase): def setUp(self): """Executed before each test in the class""" @@ -196,23 +204,24 @@ class Test1445(TestCase): def test_alias_single_word(self): """1445: Verify single-word aliases""" - self.t.config('alias.when', 'execute date') - code, out, err = self.t('when') + self.t.config("alias.when", "execute date") + code, out, err = self.t("when") self.assertEqual(0, code, "Exit code was non-zero ({0})".format(code)) self.assertIn(str(datetime.now().year), out) def test_alias_multi_word(self): """1445: Verify multi-word aliases""" - self.t.config('alias.worktasks', 'list +work') - self.t('add one +work') - self.t('add two') - code, out, err = self.t('worktasks') + self.t.config("alias.worktasks", "list +work") + self.t("add one +work") + self.t("add two") + code, out, err = self.t("worktasks") self.assertEqual(0, code, "Exit code was non-zero ({0})".format(code)) - self.assertIn('one', out) + self.assertIn("one", out) if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/annotate.test.py b/test/annotate.test.py index c0c6cf05b..210095826 100755 --- a/test/annotate.test.py +++ b/test/annotate.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -77,27 +78,45 @@ class TestAnnotate(TestCase): # NOTE: Use 'rrr' to guarantee a unique report name. Using 'r' # conflicts with 'recurring'. self.t.config("report.rrr.description", "rrr") - self.t.config("report.rrr.columns", "id,description") - self.t.config("report.rrr.sort", "id+") - self.t.config("dateformat", "m/d/Y") - self.t.config("color", "0") + self.t.config("report.rrr.columns", "id,description") + self.t.config("report.rrr.sort", "id+") + self.t.config("dateformat", "m/d/Y") + self.t.config("color", "0") code, out, err = self.t("rrr") self.assertTasksExist(out) - self.assertRegex(out, "one\n.+\\d{1,2}/\\d{1,2}/\\d{4}\\s+foo1", - msg='full - first annotation task 1') - self.assertRegex(out, "foo1\n.+\\d{1,2}/\\d{1,2}/\\d{4}\\s+foo2", - msg='full - first annotation task 1') - self.assertRegex(out, "foo2\n.+\\d{1,2}/\\d{1,2}/\\d{4}\\s+foo3", - msg='full - first annotation task 1') - self.assertRegex(out, "two\n.+\\d{1,2}/\\d{1,2}/\\d{4}\\s+bar1", - msg='full - first annotation task 1') - self.assertRegex(out, "bar1\n.+\\d{1,2}/\\d{1,2}/\\d{4}\\s+bar2", - msg='full - first annotation task 1') - self.assertRegex(out, "three\n.+\\d{1,2}/\\d{1,2}/\\d{4}\\s+baz1", - msg='full - first annotation task 1') + self.assertRegex( + out, + "one\n.+\\d{1,2}/\\d{1,2}/\\d{4}\\s+foo1", + msg="full - first annotation task 1", + ) + self.assertRegex( + out, + "foo1\n.+\\d{1,2}/\\d{1,2}/\\d{4}\\s+foo2", + msg="full - first annotation task 1", + ) + self.assertRegex( + out, + "foo2\n.+\\d{1,2}/\\d{1,2}/\\d{4}\\s+foo3", + msg="full - first annotation task 1", + ) + self.assertRegex( + out, + "two\n.+\\d{1,2}/\\d{1,2}/\\d{4}\\s+bar1", + msg="full - first annotation task 1", + ) + self.assertRegex( + out, + "bar1\n.+\\d{1,2}/\\d{1,2}/\\d{4}\\s+bar2", + msg="full - first annotation task 1", + ) + self.assertRegex( + out, + "three\n.+\\d{1,2}/\\d{1,2}/\\d{4}\\s+baz1", + msg="full - first annotation task 1", + ) def test_annotate_dateformat(self): """Testing annotations in reports using dateformat.annotation""" @@ -105,26 +124,45 @@ class TestAnnotate(TestCase): # NOTE: Use 'rrr' to guarantee a unique report name. Using 'r' # conflicts with 'recurring'. self.t.config("report.rrr.description", "rrr") - self.t.config("report.rrr.columns", "id,description") - self.t.config("report.rrr.sort", "id+") - self.t.config("dateformat.annotation", "yMD HNS") + self.t.config("report.rrr.columns", "id,description") + self.t.config("report.rrr.sort", "id+") + self.t.config("dateformat.annotation", "yMD HNS") code, out, err = self.t("rrr") self.assertTasksExist(out) - self.assertRegex(out, "one\n.+\\d{1,6}\\s+\\d{1,6}\\s+foo1", - msg="dateformat - first annotation task 1") - self.assertRegex(out, "foo1\n.+\\d{1,6}\\s+\\d{1,6}\\s+foo2", - msg="dateformat - second annotation task 1") - self.assertRegex(out, "foo2\n.+\\d{1,6}\\s+\\d{1,6}\\s+foo3", - msg="dateformat - third annotation task 1") - self.assertRegex(out, "two\n.+\\d{1,6}\\s+\\d{1,6}\\s+bar1", - msg="dateformat - first annotation task 2") - self.assertRegex(out, "bar1\n.+\\d{1,6}\\s+\\d{1,6}\\s+bar2", - msg="dateformat - second annotation task 2") - self.assertRegex(out, "three\n.+\\d{1,6}\\s+\\d{1,6}\\s+baz1", - msg="dateformat - first annotation task 3") + self.assertRegex( + out, + "one\n.+\\d{1,6}\\s+\\d{1,6}\\s+foo1", + msg="dateformat - first annotation task 1", + ) + self.assertRegex( + out, + "foo1\n.+\\d{1,6}\\s+\\d{1,6}\\s+foo2", + msg="dateformat - second annotation task 1", + ) + self.assertRegex( + out, + "foo2\n.+\\d{1,6}\\s+\\d{1,6}\\s+foo3", + msg="dateformat - third annotation task 1", + ) + self.assertRegex( + out, + "two\n.+\\d{1,6}\\s+\\d{1,6}\\s+bar1", + msg="dateformat - first annotation task 2", + ) + self.assertRegex( + out, + "bar1\n.+\\d{1,6}\\s+\\d{1,6}\\s+bar2", + msg="dateformat - second annotation task 2", + ) + self.assertRegex( + out, + "three\n.+\\d{1,6}\\s+\\d{1,6}\\s+baz1", + msg="dateformat - first annotation task 3", + ) + class TestAnnotationPropagation(TestCase): def setUp(self): @@ -138,7 +176,7 @@ class TestAnnotationPropagation(TestCase): def test_annotate_recurring(self): """Test propagation of annotation to recurring siblings""" self.t("add foo due:eom recur:weekly") - self.t("list") # GC/handleRecurrence + self.t("list") # GC/handleRecurrence self.t("2 annotate bar", input="y\n") code, out, err = self.t("all rc.verbose:nothing") @@ -194,6 +232,7 @@ class TestBug495(TestCase): code, out, err = self.t("_get 1.annotations.1.description") self.assertEqual("This is -- a -- test\n", out) + class TestBug694(TestCase): def setUp(self): self.t = Task() @@ -211,6 +250,7 @@ class TestBug694(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/append.test.py b/test/append.test.py index 589941f1c..512c00355 100755 --- a/test/append.test.py +++ b/test/append.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -89,6 +90,7 @@ class TestBug440(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/args.test.py b/test/args.test.py index 277704ad4..31281bb08 100755 --- a/test/args.test.py +++ b/test/args.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -44,27 +45,33 @@ class TestArgs(TestCase): self.t("add project:p pri:H +tag foo") code, out, err = self.t("_get 1.description") - self.assertIn("foo\n", out, msg='add project:p pri:H +tag foo') + self.assertIn("foo\n", out, msg="add project:p pri:H +tag foo") self.t("1 modify project:p pri:H +tag -- foo") code, out, err = self.t("_get 1.description") - self.assertIn("foo\n", out, msg='add project:p pri:H +tag -- foo') + self.assertIn("foo\n", out, msg="add project:p pri:H +tag -- foo") self.t("1 modify project:p pri:H -- +tag foo") code, out, err = self.t("_get 1.description") - self.assertIn("+tag foo\n", out, msg='add project:p pri:H -- +tag foo') + self.assertIn("+tag foo\n", out, msg="add project:p pri:H -- +tag foo") self.t("1 modify project:p -- pri:H +tag foo") code, out, err = self.t("_get 1.description") - self.assertIn("pri:H +tag foo\n", out, msg='add project:p -- pri:H +tag foo') + self.assertIn("pri:H +tag foo\n", out, msg="add project:p -- pri:H +tag foo") self.t("1 modify -- project:p pri:H +tag foo") code, out, err = self.t("_get 1.description") - self.assertIn("project:p pri:H +tag foo\n", out, msg='add -- project:p pri:H +tag foo') + self.assertIn( + "project:p pri:H +tag foo\n", out, msg="add -- project:p pri:H +tag foo" + ) self.t("1 modify -- project:p pri:H +tag foo --") code, out, err = self.t("_get 1.description") - self.assertIn("project:p pri:H +tag foo --\n", out, msg='add -- project:p pri:H +tag foo --') + self.assertIn( + "project:p pri:H +tag foo --\n", + out, + msg="add -- project:p pri:H +tag foo --", + ) class TestIDPosition(TestCase): @@ -94,6 +101,7 @@ class TestIDPosition(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/basetest/CMakeLists.txt b/test/basetest/CMakeLists.txt index f78450e77..67daf1190 100644 --- a/test/basetest/CMakeLists.txt +++ b/test/basetest/CMakeLists.txt @@ -5,4 +5,4 @@ configure_file(hooks.py hooks.py COPYONLY) configure_file(meta.py meta.py COPYONLY) configure_file(task.py task.py COPYONLY) configure_file(testing.py testing.py COPYONLY) -configure_file(utils.py utils.py) \ No newline at end of file +configure_file(utils.py utils.py) diff --git a/test/basetest/exceptions.py b/test/basetest/exceptions.py index 89ad8bbe9..ccab35a2d 100644 --- a/test/basetest/exceptions.py +++ b/test/basetest/exceptions.py @@ -1,25 +1,29 @@ import signal -sig_names = dict((k, v) for v, k in reversed(sorted(signal.__dict__.items())) - if v.startswith('SIG') and not v.startswith('SIG_')) +sig_names = dict( + (k, v) + for v, k in reversed(sorted(signal.__dict__.items())) + if v.startswith("SIG") and not v.startswith("SIG_") +) class CommandError(Exception): def __init__(self, cmd, code, out, err=None, msg=None): - DEFAULT = ("Command '{{0}}' was {signal}'ed. " - "SIGABRT usually means task timed out.\n") + DEFAULT = ( + "Command '{{0}}' was {signal}'ed. " + "SIGABRT usually means task timed out.\n" + ) if msg is None: msg_suffix = "\n*** Start STDOUT ***\n{2}\n*** End STDOUT ***\n" if err is not None: - msg_suffix += ( - "\n*** Start STDERR ***\n{3}\n*** End STDERR ***\n" - ) + msg_suffix += "\n*** Start STDERR ***\n{3}\n*** End STDERR ***\n" if code < 0: self.msg = DEFAULT.format(signal=sig_names[abs(code)]) else: - self.msg = ("Command '{0}' finished with unexpected exit " - "code '{1}'.\n") + self.msg = ( + "Command '{0}' finished with unexpected exit " "code '{1}'.\n" + ) self.msg += msg_suffix else: @@ -43,12 +47,12 @@ class TimeoutWaitingFor(object): self.name = name def __repr__(self): - return "*** Timeout reached while waiting for {0} ***".format( - self.name) + return "*** Timeout reached while waiting for {0} ***".format(self.name) class StreamsAreMerged(object): def __repr__(self): return "*** Streams are merged, STDERR is not available ***" + # vim: ai sts=4 et sw=4 diff --git a/test/basetest/hooks.py b/test/basetest/hooks.py index a8ff5184d..9332dc7b0 100644 --- a/test/basetest/hooks.py +++ b/test/basetest/hooks.py @@ -4,6 +4,7 @@ import os from sys import stderr import shutil import stat + try: import simplejson as json except ImportError: @@ -15,8 +16,8 @@ from .exceptions import HookError class InvalidJSON(object): - """Object representing the original unparsed JSON string and the JSON error - """ + """Object representing the original unparsed JSON string and the JSON error""" + def __init__(self, original, error): self.original = original self.error = error @@ -38,6 +39,7 @@ class Hooks(object): """Abstraction to help interact with hooks (add, remove) during tests and keep track of which are active. """ + def __init__(self, datadir): """Initialize hooks container which keeps track of active hooks and @@ -63,8 +65,7 @@ class Hooks(object): enabled = ", ".join(enabled) or None disabled = ", ".join(disabled) or None - return "".format(enabled, - disabled) + return "".format(enabled, disabled) def __getitem__(self, name): return self._hooks[name] @@ -134,8 +135,7 @@ class Hooks(object): hook._delete() def clear(self): - """Remove all existing hooks and empty the hook registry - """ + """Remove all existing hooks and empty the hook registry""" self._hooks = {} # Remove any existing hooks @@ -150,10 +150,11 @@ class Hooks(object): class Hook(object): - """Represents a hook script and provides methods to enable/disable hooks - """ - def __init__(self, hookname, hookdir, content=None, default=False, - default_hookpath=None): + """Represents a hook script and provides methods to enable/disable hooks""" + + def __init__( + self, hookname, hookdir, content=None, default=False, default_hookpath=None + ): """Initialize and create the hook This class supports creating hooks in two ways: @@ -181,24 +182,25 @@ class Hook(object): self._check_hook_not_exists(self.hookfile) if not default and content is None: - raise HookError("Cannot create hookfile {0} without content. " - "If using a builtin hook pass default=True" - .format(self.hookname)) + raise HookError( + "Cannot create hookfile {0} without content. " + "If using a builtin hook pass default=True".format(self.hookname) + ) if os.path.isfile(self.hookfile): - raise HookError("Hook with name {0} already exists. " - "Did you forget to remove() it before recreating?" - .format(self.hookname)) + raise HookError( + "Hook with name {0} already exists. " + "Did you forget to remove() it before recreating?".format(self.hookname) + ) if default: - self.default_hookfile = os.path.join(self.default_hookpath, - self.hookname) + self.default_hookfile = os.path.join(self.default_hookpath, self.hookname) self._check_hook_exists(self.default_hookfile) # Symlinks change permission of source file, cannot use one here shutil.copy(self.default_hookfile, self.hookfile) else: self.default_hookfile = None - with open(self.hookfile, 'w') as fh: + with open(self.hookfile, "w") as fh: fh.write(content) def __eq__(self, other): @@ -250,16 +252,19 @@ class Hook(object): if self.hookname.startswith(hooktype): break else: - stderr.write("WARNING: {0} is not a valid hook type. " - "It will not be triggered\n".format(self.hookname)) + stderr.write( + "WARNING: {0} is not a valid hook type. " + "It will not be triggered\n".format(self.hookname) + ) def _remove_file(self, file): try: os.remove(file) except OSError as e: if e.errno == errno.ENOENT: - raise HookError("Hook with name {0} was not found on " - "hooks/ folder".format(file)) + raise HookError( + "Hook with name {0} was not found on " "hooks/ folder".format(file) + ) else: raise @@ -271,18 +276,15 @@ class Hook(object): self._remove_hookfile(self.hookfile) def enable(self): - """Make hookfile executable to allow triggering - """ + """Make hookfile executable to allow triggering""" os.chmod(self.hookfile, stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC) def disable(self): - """Remove hookfile executable bit to deny triggering - """ + """Remove hookfile executable bit to deny triggering""" os.chmod(self.hookfile, stat.S_IREAD | stat.S_IWRITE) def is_active(self): - """Check if hook is active by verifying the execute bit - """ + """Check if hook is active by verifying the execute bit""" return os.access(self.hookfile, os.X_OK) @@ -290,6 +292,7 @@ class LoggedHook(Hook): """A variant of a Hook that allows checking that the hook was called, what was received via STDIN and what was answered to STDOUT """ + def __init__(self, *args, **kwargs): super(LoggedHook, self).__init__(*args, **kwargs) @@ -300,8 +303,7 @@ class LoggedHook(Hook): self.wrappedname = "original_" + self.hookname self.wrappedfile = os.path.join(self.hookdir, self.wrappedname) - self.original_wrapper = os.path.join(self.default_hookpath, - "wrapper.sh") + self.original_wrapper = os.path.join(self.default_hookpath, "wrapper.sh") self.hooklog_in = self.wrappedfile + ".log.in" self.hooklog_out = self.wrappedfile + ".log.out" @@ -326,11 +328,10 @@ class LoggedHook(Hook): self._remove_file(self.hooklog_out) def _setup_wrapper(self): - """Setup wrapper shell script to allow capturing input/output of hook - """ + """Setup wrapper shell script to allow capturing input/output of hook""" # Create empty hooklog to allow checking that hook executed - open(self.hooklog_in, 'w').close() - open(self.hooklog_out, 'w').close() + open(self.hooklog_in, "w").close() + open(self.hooklog_out, "w").close() # Rename the original hook to the name that will be used by wrapper self._check_hook_not_exists(self.wrappedfile) @@ -340,8 +341,7 @@ class LoggedHook(Hook): shutil.copy(self.original_wrapper, self.hookfile) def _get_log_stat(self): - """Return the most recent change timestamp and size of both logfiles - """ + """Return the most recent change timestamp and size of both logfiles""" stdin = os.stat(self.hooklog_in) stdout = os.stat(self.hooklog_out) @@ -349,8 +349,7 @@ class LoggedHook(Hook): return last_change, stdin.st_size, stdout.st_size def _use_cache(self): - """Check if log files were changed since last check - """ + """Check if log files were changed since last check""" try: last_change = self._cache["last_change"] except KeyError: @@ -367,20 +366,17 @@ class LoggedHook(Hook): return True def enable(self): - """Make hookfile executable to allow triggering - """ + """Make hookfile executable to allow triggering""" super(LoggedHook, self).enable() os.chmod(self.wrappedfile, stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC) def disable(self): - """Remove hookfile executable bit to deny triggering - """ + """Remove hookfile executable bit to deny triggering""" super(LoggedHook, self).disable() os.chmod(self.wrappedfile, stat.S_IREAD | stat.S_IWRITE) def is_active(self): - """Check if hook is active by verifying the execute bit - """ + """Check if hook is active by verifying the execute bit""" parent_is_active = super(LoggedHook, self).disable() return parent_is_active and os.access(self.wrappedfile, os.X_OK) @@ -407,16 +403,17 @@ class LoggedHook(Hook): if self._use_cache(): return self._cache["log"] - log = {"calls": [], - "input": { - "json": [], - }, - "output": { - "json": [], - "msgs": [], - }, - "exitcode": None, - } + log = { + "calls": [], + "input": { + "json": [], + }, + "output": { + "json": [], + "msgs": [], + }, + "exitcode": None, + } with open(self.hooklog_in) as fh: for i, line in enumerate(fh): @@ -426,16 +423,19 @@ class LoggedHook(Hook): # Timestamp includes nanosecond resolution timestamp = tstamp.split(" ")[-1] # convert timestamp to python datetime object - log["calls"].append({ - "timestamp": datetime.fromtimestamp(float(timestamp)), - "args": args, - }) + log["calls"].append( + { + "timestamp": datetime.fromtimestamp(float(timestamp)), + "args": args, + } + ) elif line.startswith("{"): # Decode json input (to hook) log["input"]["json"].append(json_decoder(line)) else: - raise IOError("Unexpected content on STDIN line {0}: {1}" - .format(i, line)) + raise IOError( + "Unexpected content on STDIN line {0}: {1}".format(i, line) + ) with open(self.hooklog_out) as fh: for line in fh: @@ -464,49 +464,43 @@ class LoggedHook(Hook): """ log = self.get_logs() - assert len(log["calls"]) == count, ("{0} calls expected for {1} but " - "found {2}".format( - count, - self.hookname, - log["calls"] - )) + assert ( + len(log["calls"]) == count + ), "{0} calls expected for {1} but " "found {2}".format( + count, self.hookname, log["calls"] + ) def assertExitcode(self, exitcode): - """Check if current hook finished with the expected exit code - """ + """Check if current hook finished with the expected exit code""" log = self.get_logs() - assert log["exitcode"] == exitcode, ("Expected exit code {0} for {1} " - "but found {2}".format( - exitcode, - self.hookname, - log["exitcode"] - )) + assert ( + log["exitcode"] == exitcode + ), "Expected exit code {0} for {1} " "but found {2}".format( + exitcode, self.hookname, log["exitcode"] + ) def assertValidJSONOutput(self): - """Check if current hook output is valid JSON in all expected replies - """ + """Check if current hook output is valid JSON in all expected replies""" log = self.get_logs() for i, out in enumerate(log["output"]["json"]): - assert not isinstance(out, InvalidJSON), ("Invalid JSON found at " - "reply number {0} with " - "content {1}".format( - i + 1, - out.original - )) + assert not isinstance(out, InvalidJSON), ( + "Invalid JSON found at " + "reply number {0} with " + "content {1}".format(i + 1, out.original) + ) def assertInvalidJSONOutput(self): - """Check if current hook output is invalid JSON in any expected reply - """ + """Check if current hook output is invalid JSON in any expected reply""" log = self.get_logs() for i, out in enumerate(log["output"]["json"]): - assert isinstance(out, InvalidJSON), ("Valid JSON found at reply " - "number {0} with content " - "{1}".format( - i + 1, - out.original - )) + assert isinstance(out, InvalidJSON), ( + "Valid JSON found at reply " + "number {0} with content " + "{1}".format(i + 1, out.original) + ) + # vim: ai sts=4 et sw=4 diff --git a/test/basetest/meta.py b/test/basetest/meta.py index 055f5ca95..f5b30a5ad 100644 --- a/test/basetest/meta.py +++ b/test/basetest/meta.py @@ -7,6 +7,7 @@ class MetaTest(type): Creates test_methods in the TestCase class dynamically named after the arguments used. """ + @staticmethod def make_function(classname, *args, **kwargs): def test(self): @@ -35,4 +36,5 @@ class MetaTest(type): return super(MetaTest, meta).__new__(meta, classname, bases, dct) + # vim: ai sts=4 et sw=4 diff --git a/test/basetest/task.py b/test/basetest/task.py index d426ff9db..be30441b7 100644 --- a/test/basetest/task.py +++ b/test/basetest/task.py @@ -21,6 +21,7 @@ class Task(object): A taskw client should not be used after being destroyed. """ + DEFAULT_TASK = task_binary_location() def __init__(self, taskw=DEFAULT_TASK): @@ -43,11 +44,13 @@ class Task(object): self.reset_env() - with open(self.taskrc, 'w') as rc: - rc.write("data.location={0}\n" - "hooks=off\n" - "news.version=2.6.0\n" - "".format(self.datadir)) + with open(self.taskrc, "w") as rc: + rc.write( + "data.location={0}\n" + "hooks=off\n" + "news.version=2.6.0\n" + "".format(self.datadir) + ) # Hooks disabled until requested self.hooks = None @@ -61,14 +64,12 @@ class Task(object): return self.runSuccess(*args, **kwargs) def activate_hooks(self): - """Enable self.hooks functionality and activate hooks on config - """ + """Enable self.hooks functionality and activate hooks on config""" self.config("hooks", "1") self.hooks = Hooks(self.datadir) def reset_env(self): - """Set a new environment derived from the one used to launch the test - """ + """Set a new environment derived from the one used to launch the test""" # Copy all env variables to avoid clashing subprocess environments self.env = os.environ.copy() @@ -78,15 +79,13 @@ class Task(object): self.env["TASKRC"] = self.taskrc def config(self, var, value): - """Run setup `var` as `value` in taskd config - """ + """Run setup `var` as `value` in taskd config""" # Add -- to avoid misinterpretation of - in things like UUIDs cmd = (self.taskw, "config", "--", var, value) return run_cmd_wait(cmd, env=self.env, input="y\n") def del_config(self, var): - """Remove `var` from taskd config - """ + """Remove `var` from taskd config""" cmd = (self.taskw, "config", var) return run_cmd_wait(cmd, env=self.env, input="y\n") @@ -104,8 +103,9 @@ class Task(object): if export_filter is None: export_filter = "" - code, out, err = self.runSuccess("rc.json.array=1 {0} export" - "".format(export_filter)) + code, out, err = self.runSuccess( + "rc.json.array=1 {0} export" "".format(export_filter) + ) return json.loads(out) @@ -118,16 +118,16 @@ class Task(object): result = self.export(export_filter=export_filter) if len(result) != 1: - descriptions = [task.get('description') or '[description-missing]' - for task in result] + descriptions = [ + task.get("description") or "[description-missing]" for task in result + ] raise ValueError( "One task should match the '{0}' filter, '{1}' " "matches:\n {2}".format( - export_filter or '', - len(result), - '\n '.join(descriptions) - )) + export_filter or "", len(result), "\n ".join(descriptions) + ) + ) return result[0] @@ -146,8 +146,7 @@ class Task(object): return args - def runSuccess(self, args="", input=None, merge_streams=False, - timeout=5): + def runSuccess(self, args="", input=None, merge_streams=False, timeout=5): """Invoke task with given arguments and fail if exit code != 0 Use runError if you want exit_code to be tested automatically and @@ -171,10 +170,9 @@ class Task(object): args = self._split_string_args_if_string(args) command.extend(args) - output = run_cmd_wait_nofail(command, input, - merge_streams=merge_streams, - env=self.env, - timeout=timeout) + output = run_cmd_wait_nofail( + command, input, merge_streams=merge_streams, env=self.env, timeout=timeout + ) if output[0] != 0: raise CommandError(command, *output) @@ -205,10 +203,9 @@ class Task(object): args = self._split_string_args_if_string(args) command.extend(args) - output = run_cmd_wait_nofail(command, input, - merge_streams=merge_streams, - env=self.env, - timeout=timeout) + output = run_cmd_wait_nofail( + command, input, merge_streams=merge_streams, env=self.env, timeout=timeout + ) # output[0] is the exit code if output[0] == 0 or output[0] is None: @@ -217,8 +214,7 @@ class Task(object): return output def destroy(self): - """Cleanup the data folder and release server port for other instances - """ + """Cleanup the data folder and release server port for other instances""" try: shutil.rmtree(self.datadir) except OSError as e: @@ -237,8 +233,10 @@ class Task(object): self.destroy = lambda: None def __destroyed(self, *args, **kwargs): - raise AttributeError("Task instance has been destroyed. " - "Create a new instance if you need a new client.") + raise AttributeError( + "Task instance has been destroyed. " + "Create a new instance if you need a new client." + ) def diag(self, merge_streams_with=None): """Run task diagnostics. @@ -302,4 +300,5 @@ class Task(object): # Use advanced time format self._command = [cmd, "-f", faketime] + self._command + # vim: ai sts=4 et sw=4 diff --git a/test/basetest/testing.py b/test/basetest/testing.py index ab6a026cc..56154f925 100644 --- a/test/basetest/testing.py +++ b/test/basetest/testing.py @@ -7,14 +7,14 @@ class BaseTestCase(unittest.TestCase): def tap(self, out): sys.stderr.write("--- tap output start ---\n") for line in out.splitlines(): - sys.stderr.write(line + '\n') + sys.stderr.write(line + "\n") sys.stderr.write("--- tap output end ---\n") @unittest.skipIf(TASKW_SKIP, "TASKW_SKIP set, skipping task tests.") class TestCase(BaseTestCase): - """Automatically skips tests if TASKW_SKIP is present in the environment - """ + """Automatically skips tests if TASKW_SKIP is present in the environment""" + pass diff --git a/test/basetest/utils.py b/test/basetest/utils.py index 9bcb6bc06..2d665d8c3 100644 --- a/test/basetest/utils.py +++ b/test/basetest/utils.py @@ -9,11 +9,13 @@ import atexit import tempfile from subprocess import Popen, PIPE, STDOUT from threading import Thread + try: from Queue import Queue, Empty except ImportError: from queue import Queue, Empty from time import sleep + try: import simplejson as json except ImportError: @@ -21,15 +23,13 @@ except ImportError: from .exceptions import CommandError, TimeoutWaitingFor USED_PORTS = set() -ON_POSIX = 'posix' in sys.builtin_module_names +ON_POSIX = "posix" in sys.builtin_module_names # Directory relative to basetest module location CURRENT_DIR = os.path.dirname(os.path.abspath(__file__)) # Location of binary files (usually the src/ folder) -BIN_PREFIX = os.path.abspath( - os.path.join("${CMAKE_BINARY_DIR}","src") -) +BIN_PREFIX = os.path.abspath(os.path.join("${CMAKE_BINARY_DIR}", "src")) # Default location of test hooks DEFAULT_HOOK_PATH = os.path.abspath( @@ -45,7 +45,7 @@ TASKW_SKIP = os.environ.get("TASKW_SKIP", False) # Environment flags to control use of PATH or in-tree binaries TASK_USE_PATH = os.environ.get("TASK_USE_PATH", False) -UUID_REGEXP = ("[0-9A-Fa-f]{8}-" + ("[0-9A-Fa-f]{4}-" * 3) + "[0-9A-Fa-f]{12}") +UUID_REGEXP = "[0-9A-Fa-f]{8}-" + ("[0-9A-Fa-f]{4}-" * 3) + "[0-9A-Fa-f]{12}" def task_binary_location(cmd="task"): @@ -65,9 +65,8 @@ def binary_location(cmd, USE_PATH=False): return os.path.join(BIN_PREFIX, cmd) -def wait_condition(cond, timeout=10, sleeptime=.01): - """Wait for condition to return anything other than None - """ +def wait_condition(cond, timeout=10, sleeptime=0.01): + """Wait for condition to return anything other than None""" # NOTE Increasing sleeptime can dramatically increase testsuite runtime # It also reduces CPU load significantly if timeout is None: @@ -92,8 +91,8 @@ def wait_condition(cond, timeout=10, sleeptime=.01): def wait_process(pid, timeout=None): - """Wait for process to finish - """ + """Wait for process to finish""" + def process(): try: os.kill(pid, 0) @@ -120,13 +119,18 @@ def _queue_output(arguments, pidq, outputq): # pid None is read by the main thread as a crash of the process pidq.put(None) - outputq.put(( - "", - ("Unexpected exception caught during execution of taskw: '{0}' . " - "If you are running out-of-tree tests set TASK_USE_PATH=1 " - "in shell env before execution and add the " - "location of the task(d) binary to the PATH".format(e)), - 255)) # false exitcode + outputq.put( + ( + "", + ( + "Unexpected exception caught during execution of taskw: '{0}' . " + "If you are running out-of-tree tests set TASK_USE_PATH=1 " + "in shell env before execution and add the " + "location of the task(d) binary to the PATH".format(e) + ), + 255, + ) + ) # false exitcode return @@ -137,15 +141,14 @@ def _queue_output(arguments, pidq, outputq): out, err = proc.communicate(input_data) if sys.version_info > (3,): - out, err = out.decode('utf-8'), err.decode('utf-8') + out, err = out.decode("utf-8"), err.decode("utf-8") # Give the output back to the caller outputq.put((out, err, proc.returncode)) def _retrieve_output(thread, timeout, queue, thread_error): - """Fetch output from taskw subprocess queues - """ + """Fetch output from taskw subprocess queues""" # Try to join the thread on failure abort thread.join(timeout) if thread.is_alive(): @@ -184,16 +187,16 @@ def _get_output(arguments, timeout=None): # Process crashed or timed out for some reason if pid is None: - return _retrieve_output(t, output_timeout, outputq, - "TaskWarrior to start") + return _retrieve_output(t, output_timeout, outputq, "TaskWarrior to start") # Wait for process to finish (normal execution) state = wait_process(pid, timeout) if state: # Process finished - return _retrieve_output(t, output_timeout, outputq, - "TaskWarrior thread to join") + return _retrieve_output( + t, output_timeout, outputq, "TaskWarrior thread to join" + ) # If we reach this point we assume the process got stuck or timed out for sig in (signal.SIGABRT, signal.SIGTERM, signal.SIGKILL): @@ -210,15 +213,21 @@ def _get_output(arguments, timeout=None): if state: # Process finished - return _retrieve_output(t, output_timeout, outputq, - "TaskWarrior to die") + return _retrieve_output(t, output_timeout, outputq, "TaskWarrior to die") # This should never happen but in case something goes really bad raise OSError("TaskWarrior stopped responding and couldn't be killed") -def run_cmd_wait(cmd, input=None, stdout=PIPE, stderr=PIPE, - merge_streams=False, env=os.environ, timeout=None): +def run_cmd_wait( + cmd, + input=None, + stdout=PIPE, + stderr=PIPE, + merge_streams=False, + env=os.environ, + timeout=None, +): "Run a subprocess and wait for it to finish" if input is None: @@ -265,8 +274,7 @@ def run_cmd_wait_nofail(*args, **kwargs): def memoize(obj): - """Keep an in-memory cache of function results given its inputs - """ + """Keep an in-memory cache of function results given its inputs""" cache = obj.cache = {} @functools.wraps(obj) @@ -275,11 +283,13 @@ def memoize(obj): if key not in cache: cache[key] = obj(*args, **kwargs) return cache[key] + return memoizer try: from shutil import which + which = memoize(which) except ImportError: # NOTE: This is shutil.which backported from python-3.3.3 @@ -294,12 +304,12 @@ except ImportError: path. """ + # Check that a given file can be accessed with the correct mode. # Additionally check that `file` is not a directory, as on Windows # directories pass the os.access check. def _access_check(fn, mode): - return (os.path.exists(fn) and os.access(fn, mode) and - not os.path.isdir(fn)) + return os.path.exists(fn) and os.access(fn, mode) and not os.path.isdir(fn) # If we're given a path with a directory part, look it up directly # rather than referring to PATH directories. This includes checking @@ -348,16 +358,15 @@ except ImportError: def parse_datafile(file): - """Parse .data files on the client and server treating files as JSON - """ + """Parse .data files on the client and server treating files as JSON""" data = [] with open(file) as fh: for line in fh: line = line.rstrip("\n") # Turn [] strings into {} to be treated properly as JSON hashes - if line.startswith('[') and line.endswith(']'): - line = '{' + line[1:-1] + '}' + if line.startswith("[") and line.endswith("]"): + line = "{" + line[1:-1] + "}" if line.startswith("{"): data.append(json.loads(line)) @@ -370,6 +379,7 @@ def mkstemp(data): """ Create a temporary file that is removed at process exit """ + def rmtemp(name): try: os.remove(name) @@ -377,7 +387,7 @@ def mkstemp(data): pass f = tempfile.NamedTemporaryFile(delete=False) - f.write(data.encode('utf-8') if not isinstance(data, bytes) else data) + f.write(data.encode("utf-8") if not isinstance(data, bytes) else data) f.close() # Ensure removal at end of python session @@ -387,11 +397,11 @@ def mkstemp(data): def mkstemp_exec(data): - """Create a temporary executable file that is removed at process exit - """ + """Create a temporary executable file that is removed at process exit""" name = mkstemp(data) os.chmod(name, 0o755) return name + # vim: ai sts=4 et sw=4 diff --git a/test/bash_completion.test.py b/test/bash_completion.test.py index 6730236b7..360fe7d8d 100755 --- a/test/bash_completion.test.py +++ b/test/bash_completion.test.py @@ -29,6 +29,7 @@ import sys import os import unittest from contextlib import contextmanager + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -66,16 +67,18 @@ def prepare_tasksh(t): tasksh.append(line) - tasksh.extend([ - 'COMP_WORDS=("$@")', - 'COMP_CWORD=$(($#-1))', - '_task', - 'for reply_iter in "${COMPREPLY[@]}"; do', - ' echo $reply_iter', - 'done', - ]) + tasksh.extend( + [ + 'COMP_WORDS=("$@")', + "COMP_CWORD=$(($#-1))", + "_task", + 'for reply_iter in "${COMPREPLY[@]}"; do', + " echo $reply_iter", + "done", + ] + ) - return '\n'.join(tasksh) + return "\n".join(tasksh) class TestBashCompletionBase(TestCase): @@ -88,7 +91,7 @@ class TestBashCompletionBase(TestCase): self.t.tasksh_script = os.path.join(self.t.datadir, "task.sh") - with open(self.t.tasksh_script, 'w') as tasksh: + with open(self.t.tasksh_script, "w") as tasksh: tasksh.write(prepare_tasksh(self.t)) @@ -170,6 +173,7 @@ class TestProject(TestBashCompletionBase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/blocked.test.py b/test/blocked.test.py index b673f76f0..0eae3d2c4 100755 --- a/test/blocked.test.py +++ b/test/blocked.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + sys.path.append(os.path.dirname(os.path.abspath(__file__))) from basetest import Task, TestCase @@ -49,6 +50,7 @@ class TestBug1381(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/bulk.test.py b/test/bulk.test.py index 75f7adc79..e66c13aad 100755 --- a/test/bulk.test.py +++ b/test/bulk.test.py @@ -29,6 +29,7 @@ import sys import os import signal import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -138,7 +139,9 @@ class TestBulk(TestCase): self.assertNotIn("Deleting task", out) # Test with 3 tasks, denying delete. - code, out, err = self.t.runError("1-3 delete rc.confirmation:1", input="n\nn\nn\n") + code, out, err = self.t.runError( + "1-3 delete rc.confirmation:1", input="n\nn\nn\n" + ) self.assertNotIn("(yes/no)", out) self.assertIn("(yes/no/all/quit)", out) self.assertNotIn("Deleted task 1", out) @@ -208,6 +211,7 @@ class TestBugBulk(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/burndown.test.py b/test/burndown.test.py index ce5d18ae7..9c31cd7a3 100755 --- a/test/burndown.test.py +++ b/test/burndown.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -97,6 +98,7 @@ class TestBurndownCommand(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/calc.test.py b/test/calc.test.py index 7072aca70..1eb10c72a 100755 --- a/test/calc.test.py +++ b/test/calc.test.py @@ -30,6 +30,7 @@ import os import re import signal import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -39,8 +40,9 @@ from basetest.utils import BIN_PREFIX, run_cmd_wait, run_cmd_wait_nofail CALC = os.path.join(BIN_PREFIX, "calc") -@unittest.skipIf(not os.path.isfile(CALC), - "calc binary not available in {0}".format(CALC)) +@unittest.skipIf( + not os.path.isfile(CALC), "calc binary not available in {0}".format(CALC) +) class TestCalc(TestCase): def test_regular_math(self): """regular math""" @@ -56,7 +58,9 @@ class TestCalc(TestCase): def test_postfix_math(self): """postfix math""" - code, out, err = run_cmd_wait((CALC, "--debug", "--postfix", "12 3600 * 34 60 * 56 + +")) + code, out, err = run_cmd_wait( + (CALC, "--debug", "--postfix", "12 3600 * 34 60 * 56 + +") + ) self.assertIn("Eval literal number ↑'12'", out) self.assertIn("Eval literal number ↑'3600'", out) @@ -122,18 +126,17 @@ class TestBug1254(TestCase): self.assertEqual(expected, code, "Exit code was non-zero ({0})".format(code)) def test_no_segmentation_fault_calc_negative_multiplication(self): - """1254: calc can multiply zero and negative numbers - """ + """1254: calc can multiply zero and negative numbers""" self.run_command("calc 0*-1") def test_calc_positive_multiplication(self): - """1254: calc can multiply negative zero and positive - """ + """1254: calc can multiply negative zero and positive""" self.run_command("calc 0*1") if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/calendar.test.py b/test/calendar.test.py index 52a13b8dd..40089df81 100755 --- a/test/calendar.test.py +++ b/test/calendar.test.py @@ -29,6 +29,7 @@ import sys import os import unittest from datetime import datetime, timedelta + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -38,6 +39,7 @@ from basetest import Task, TestCase def timestamp_in_holiday_format(time): return time.strftime("%Y%m%d") + class TestCalendarCommandLine(TestCase): def setUp(self): """Executed before each test in the class""" @@ -56,7 +58,9 @@ class TestCalendarCommandLine(TestCase): def test_basic_command_offset(self): """Verify 'calendar rc.calendar.offset:on rc.calendar.offset.value:1' does not fail""" - code, out, err = self.t("calendar rc.calendar.offset:on rc.calendar.offset.value:1") + code, out, err = self.t( + "calendar rc.calendar.offset:on rc.calendar.offset.value:1" + ) self.assertIn("Su Mo Tu We Th Fr Sa", out) def test_basic_command(self): @@ -72,13 +76,17 @@ class TestCalendarCommandLine(TestCase): def test_basic_command_details(self): """Verify 'calendar rc.calendar.details:full rc.calendar.details.report:list' does not fail""" self.t("add task_with_due_date due:tomorrow") - code, out, err = self.t("calendar rc.calendar.details:full rc.calendar.details.report:list") + code, out, err = self.t( + "calendar rc.calendar.details:full rc.calendar.details.report:list" + ) self.assertIn("task_with_due_date", out) def test_basic_command_details_color(self): """Verify 'calendar rc.calendar.details:full rc.calendar.details.report:list rc._forcecolor:on' does not fail""" self.t("add task_with_due_date due:tomorrow") - code, out, err = self.t("calendar rc.calendar.details:full rc.calendar.details.report:list rc._forcecolor:on") + code, out, err = self.t( + "calendar rc.calendar.details:full rc.calendar.details.report:list rc._forcecolor:on" + ) self.assertIn("task_with_due_date", out) def test_basic_command_holidays(self): @@ -88,29 +96,37 @@ class TestCalendarCommandLine(TestCase): def test_basic_command_single_holiday(self): """Verify 'calendar rc.holiday.test.name:donkeyday rc.holiday.test.date:[tomorrws date] rc.calendar.holidays:full' does not fail""" - code, out, err = self.t("calendar rc.holiday.test.name:donkeyday rc.holliday.test.date:{0} rc.calendar.holidays:full".format(self.tomorrow)) + code, out, err = self.t( + "calendar rc.holiday.test.name:donkeyday rc.holliday.test.date:{0} rc.calendar.holidays:full".format( + self.tomorrow + ) + ) self.assertRegex(out, "Date +Holiday") def test_basic_command_multiday_holiday(self): """Verify 'calendar rc.holiday.test.name:donkeyday rc.holiday.test.start:[tomorrws date] rc.holiday.test.end:[date a month later] rc.calendar.holidays:full' does not fail""" - code, out, err = self.t("calendar rc.holiday.test.name:donkeyday rc.holiday.test.start:{0} rc.holiday.test.end:{1} rc.calendar.holidays:full".format(self.tomorrow, self.next_month)) + code, out, err = self.t( + "calendar rc.holiday.test.name:donkeyday rc.holiday.test.start:{0} rc.holiday.test.end:{1} rc.calendar.holidays:full".format( + self.tomorrow, self.next_month + ) + ) self.assertRegex(out, "Date +Holiday") def test_y_argument(self): """Verify 'calendar y' does not fail""" code, out, err = self.t("calendar y") - self.assertIn("January", out) - self.assertIn("February", out) - self.assertIn("March", out) - self.assertIn("April", out) - self.assertIn("May", out) - self.assertIn("June", out) - self.assertIn("July", out) - self.assertIn("August", out) + self.assertIn("January", out) + self.assertIn("February", out) + self.assertIn("March", out) + self.assertIn("April", out) + self.assertIn("May", out) + self.assertIn("June", out) + self.assertIn("July", out) + self.assertIn("August", out) self.assertIn("September", out) - self.assertIn("October", out) - self.assertIn("November", out) - self.assertIn("December", out) + self.assertIn("October", out) + self.assertIn("November", out) + self.assertIn("December", out) self.assertNotIn("Could not recognize argument", err) def test_due_argument(self): @@ -249,6 +265,7 @@ class TestCalendarCommandLine(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/caseless.test.py b/test/caseless.test.py index 5e6e46cdc..9e3ade09a 100755 --- a/test/caseless.test.py +++ b/test/caseless.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -38,11 +39,11 @@ class TestCaseless(TestCase): @classmethod def setUpClass(cls): """Executed once before any test in the class""" - cls.t = Task () + cls.t = Task() cls.t.config("report.ls.columns", "id,project,priority,description") - cls.t.config("report.ls.labels", "ID,Proj,Pri,Description") - cls.t.config("report.ls.sort", "priority-,project+") - cls.t.config("report.ls.filter", "status:pending") + cls.t.config("report.ls.labels", "ID,Proj,Pri,Description") + cls.t.config("report.ls.sort", "priority-,project+") + cls.t.config("report.ls.filter", "status:pending") def setUp(self): """Executed before each test in the class""" @@ -102,21 +103,30 @@ class TestCaseless(TestCase): def test_annotation_filter(self): """Verify annotation filter with and without case sensitivity""" - code, out, err = self.t.runError("rc.search.case.sensitive:yes ls description.contains:Three") + code, out, err = self.t.runError( + "rc.search.case.sensitive:yes ls description.contains:Three" + ) self.assertNotIn("one two three", out) - code, out, err = self.t("rc.search.case.sensitive:no ls description.contains:Three") + code, out, err = self.t( + "rc.search.case.sensitive:no ls description.contains:Three" + ) self.assertIn("one two three", out) - code, out, err = self.t.runError("rc.search.case.sensitive:yes ls description.contains:Six") + code, out, err = self.t.runError( + "rc.search.case.sensitive:yes ls description.contains:Six" + ) self.assertNotIn("one two three", out) - code, out, err = self.t("rc.search.case.sensitive:no ls description.contains:Six") + code, out, err = self.t( + "rc.search.case.sensitive:no ls description.contains:Six" + ) self.assertIn("one two three", out) if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/col.test.cpp b/test/col.test.cpp index c4be0ea4f..0e7d8290b 100644 --- a/test/col.test.cpp +++ b/test/col.test.cpp @@ -27,19 +27,18 @@ #include // cmake.h include header must come first -#include #include #include +#include #include //////////////////////////////////////////////////////////////////////////////// -int main (int, char**) -{ - UnitTest test (12); +int main(int, char**) { + UnitTest test(12); // Ensure environment has no influence. - unsetenv ("TASKDATA"); - unsetenv ("TASKRC"); + unsetenv("TASKDATA"); + unsetenv("TASKRC"); ColumnID columnID; unsigned int minimum = 0; @@ -47,37 +46,36 @@ int main (int, char**) Task t1; t1.id = 3; - columnID.measure (t1, minimum, maximum); - test.is ((int)minimum, 1, "id:3 --> ColID::measure minimum 1"); - test.is ((int)maximum, 1, "id:3 --> ColID::measure maximum 1"); + columnID.measure(t1, minimum, maximum); + test.is((int)minimum, 1, "id:3 --> ColID::measure minimum 1"); + test.is((int)maximum, 1, "id:3 --> ColID::measure maximum 1"); t1.id = 33; - columnID.measure (t1, minimum, maximum); - test.is ((int)minimum, 2, "id:33 --> ColID::measure minimum 2"); - test.is ((int)maximum, 2, "id:33 --> ColID::measure maximum 2"); + columnID.measure(t1, minimum, maximum); + test.is((int)minimum, 2, "id:33 --> ColID::measure minimum 2"); + test.is((int)maximum, 2, "id:33 --> ColID::measure maximum 2"); t1.id = 333; - columnID.measure (t1, minimum, maximum); - test.is ((int)minimum, 3, "id:333 --> ColID::measure minimum 3"); - test.is ((int)maximum, 3, "id:333 --> ColID::measure maximum 3"); + columnID.measure(t1, minimum, maximum); + test.is((int)minimum, 3, "id:333 --> ColID::measure minimum 3"); + test.is((int)maximum, 3, "id:333 --> ColID::measure maximum 3"); t1.id = 3333; - columnID.measure (t1, minimum, maximum); - test.is ((int)minimum, 4, "id:3333 --> ColID::measure minimum 4"); - test.is ((int)maximum, 4, "id:3333 --> ColID::measure maximum 4"); + columnID.measure(t1, minimum, maximum); + test.is((int)minimum, 4, "id:3333 --> ColID::measure minimum 4"); + test.is((int)maximum, 4, "id:3333 --> ColID::measure maximum 4"); t1.id = 33333; - columnID.measure (t1, minimum, maximum); - test.is ((int)minimum, 5, "id:33333 --> ColID::measure minimum 5"); - test.is ((int)maximum, 5, "id:33333 --> ColID::measure maximum 5"); + columnID.measure(t1, minimum, maximum); + test.is((int)minimum, 5, "id:33333 --> ColID::measure minimum 5"); + test.is((int)maximum, 5, "id:33333 --> ColID::measure maximum 5"); t1.id = 333333; - columnID.measure (t1, minimum, maximum); - test.is ((int)minimum, 6, "id:333333 --> ColID::measure minimum 6"); - test.is ((int)maximum, 6, "id:333333 --> ColID::measure maximum 6"); + columnID.measure(t1, minimum, maximum); + test.is((int)minimum, 6, "id:333333 --> ColID::measure minimum 6"); + test.is((int)maximum, 6, "id:333333 --> ColID::measure maximum 6"); return 0; } //////////////////////////////////////////////////////////////////////////////// - diff --git a/test/color.cmd.test.py b/test/color.cmd.test.py index 305d1dab3..17e20865e 100755 --- a/test/color.cmd.test.py +++ b/test/color.cmd.test.py @@ -29,6 +29,7 @@ import sys import os import unittest import platform + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -45,12 +46,12 @@ class TestColorCommand(TestCase): self.t = Task() def test_colors_off(self): - """ Verify 'task colors' shows an error with color:off""" + """Verify 'task colors' shows an error with color:off""" code, out, err = self.t.runError("colors") self.assertIn("Color is currently turned off", out) def test_colors_all(self): - """ Verify 'task colors' shows all colors""" + """Verify 'task colors' shows all colors""" code, out, err = self.t("colors rc._forcecolor:on") self.assertIn("Basic colors", out) self.assertIn("Effects", out) @@ -60,12 +61,12 @@ class TestColorCommand(TestCase): self.assertIn("Try running 'task color white on red'.", out) def test_colors_sample(self): - """ Verify 'task colors red' shows a sample""" + """Verify 'task colors red' shows a sample""" code, out, err = self.t("colors rc._forcecolor:on red") self.assertRegex(out, "Your sample:\n\n .\\[31mtask color red.\\[0m") def test_colors_legend(self): - """ Verify 'task colors legend' shows theme colors""" + """Verify 'task colors legend' shows theme colors""" code, out, err = self.t("colors rc._forcecolor:on legend") self.assertRegex(out, r"color.debug\s+.\[0m\s.\[38;5;4mcolor4\s+.\[0m") @@ -74,8 +75,10 @@ class TestColorCommand(TestCase): code, out, err = self.t("colors rc._forcecolor:on rc.color.debug:red legend") self.assertRegex(out, r"color.debug\s+.\[0m\s.\[31mred\s+.\[0m") + if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/color.rules.test.py b/test/color.rules.test.py index 52cc4026a..422ae25a1 100755 --- a/test/color.rules.test.py +++ b/test/color.rules.test.py @@ -29,6 +29,7 @@ import sys import os import unittest import platform + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -42,181 +43,182 @@ class TestColorRules(TestCase): cls.t = Task() # Controlling peripheral color. - cls.t.config('_forcecolor', 'on') - cls.t.config('fontunderline', 'off') # label underlining complicates the tests. - cls.t.config('color.alternate', '') # alternating color complicateѕ the tests. - cls.t.config('default.command', 'list') - cls.t.config('uda.xxx.type', 'numeric') - cls.t.config('uda.xxx.label', 'XXX') + cls.t.config("_forcecolor", "on") + cls.t.config("fontunderline", "off") # label underlining complicates the tests. + cls.t.config("color.alternate", "") # alternating color complicateѕ the tests. + cls.t.config("default.command", "list") + cls.t.config("uda.xxx.type", "numeric") + cls.t.config("uda.xxx.label", "XXX") # Color rules. - cls.t.config('color.active', 'red') - cls.t.config('color.blocked', 'red') - cls.t.config('color.blocking', 'blue') - cls.t.config('color.due', 'red') - cls.t.config('color.overdue', 'blue') - cls.t.config('color.error', 'blue') - cls.t.config('color.header', 'blue') - cls.t.config('color.footnote', 'red') - cls.t.config('color.debug', 'green') - cls.t.config('color.project.x', 'red') - cls.t.config('color.project.none', '') - cls.t.config('color.uda.priority.H', 'red') - cls.t.config('color.uda.priority.M', 'blue') - cls.t.config('color.uda.priority.L', 'green') - cls.t.config('color.keyword.keyword', 'red') - cls.t.config('color.tagged', '') - cls.t.config('color.tag.none', '') - cls.t.config('color.tag.x', 'red') - cls.t.config('color.recurring', 'red') - cls.t.config('color.uda.xxx', 'red') - cls.t.config('color.uda.xxx.4', 'blue') + cls.t.config("color.active", "red") + cls.t.config("color.blocked", "red") + cls.t.config("color.blocking", "blue") + cls.t.config("color.due", "red") + cls.t.config("color.overdue", "blue") + cls.t.config("color.error", "blue") + cls.t.config("color.header", "blue") + cls.t.config("color.footnote", "red") + cls.t.config("color.debug", "green") + cls.t.config("color.project.x", "red") + cls.t.config("color.project.none", "") + cls.t.config("color.uda.priority.H", "red") + cls.t.config("color.uda.priority.M", "blue") + cls.t.config("color.uda.priority.L", "green") + cls.t.config("color.keyword.keyword", "red") + cls.t.config("color.tagged", "") + cls.t.config("color.tag.none", "") + cls.t.config("color.tag.x", "red") + cls.t.config("color.recurring", "red") + cls.t.config("color.uda.xxx", "red") + cls.t.config("color.uda.xxx.4", "blue") - cls.t('add control task') # 1 - cls.t('add active task') # 2 - cls.t('2 start') - cls.t('add blocked task') # 3 - cls.t('add blocking task') # 4 - cls.t('3 modify depends:4') - cls.t('add tomorrow due:tomorrow') # 5 - cls.t('add yesterday due:yesterday') # 6 - cls.t('add anhourago due:now-1h') # 7 - cls.t('add someday due:yesterday') # 8 - cls.t('add project_x project:x') # 9 - cls.t('add pri_h priority:H') # 10 - cls.t('add pri_m priority:M') # 11 - cls.t('add pri_l priority:L') # 12 - cls.t('add keyword') # 13 - cls.t('add tag_x +x') # 14 - cls.t('add uda_xxx_1 xxx:1') # 15 - cls.t('add uda_xxx_4 xxx:4') # 16 - cls.t('add recurring due:tomorrow recur:1week') # 17 Keep this last + cls.t("add control task") # 1 + cls.t("add active task") # 2 + cls.t("2 start") + cls.t("add blocked task") # 3 + cls.t("add blocking task") # 4 + cls.t("3 modify depends:4") + cls.t("add tomorrow due:tomorrow") # 5 + cls.t("add yesterday due:yesterday") # 6 + cls.t("add anhourago due:now-1h") # 7 + cls.t("add someday due:yesterday") # 8 + cls.t("add project_x project:x") # 9 + cls.t("add pri_h priority:H") # 10 + cls.t("add pri_m priority:M") # 11 + cls.t("add pri_l priority:L") # 12 + cls.t("add keyword") # 13 + cls.t("add tag_x +x") # 14 + cls.t("add uda_xxx_1 xxx:1") # 15 + cls.t("add uda_xxx_4 xxx:4") # 16 + cls.t("add recurring due:tomorrow recur:1week") # 17 Keep this last def test_control(self): """No color on control task.""" - code, out, err = self.t('1 info') - self.assertNotIn('\x1b[', out) + code, out, err = self.t("1 info") + self.assertNotIn("\x1b[", out) def test_disable_in_pipe(self): """No color in pipe unless forced.""" - code, out, err = self.t('2 info rc._forcecolor:off') - self.assertNotIn('\x1b[', out) + code, out, err = self.t("2 info rc._forcecolor:off") + self.assertNotIn("\x1b[", out) def test_active(self): """Active color rule.""" - code, out, err = self.t('/active/ info') - self.assertIn('\x1b[31m', out) + code, out, err = self.t("/active/ info") + self.assertIn("\x1b[31m", out) def test_blocked(self): """Blocked color rule.""" - code, out, err = self.t('/blocked/ info') - self.assertIn('\x1b[31m', out) + code, out, err = self.t("/blocked/ info") + self.assertIn("\x1b[31m", out) def test_blocking(self): """Blocking color rule.""" - code, out, err = self.t('/blocking/ info') - self.assertIn('\x1b[34m', out) + code, out, err = self.t("/blocking/ info") + self.assertIn("\x1b[34m", out) def test_due_yesterday(self): """Overdue color rule.""" - code, out, err = self.t('/yesterday/ info') - self.assertIn('\x1b[34m', out) + code, out, err = self.t("/yesterday/ info") + self.assertIn("\x1b[34m", out) def test_due_anhourago(self): """Overdue color rule from an hour ago.""" - code, out, err = self.t('/anhourago/ info') + code, out, err = self.t("/anhourago/ info") # Match 4-bit or 8-bit blue color code - self.assertRegex(out, '\x1b\\[(38;5;4|34)m') + self.assertRegex(out, "\x1b\\[(38;5;4|34)m") def test_due_tomorrow(self): """Due tomorrow color rule.""" - code, out, err = self.t('/tomorrow/ info') - self.assertIn('\x1b[31m', out) + code, out, err = self.t("/tomorrow/ info") + self.assertIn("\x1b[31m", out) def test_due_someday(self): """Due someday color rule.""" - code, out, err = self.t('/someday/ info') - self.assertIn('\x1b[', out) + code, out, err = self.t("/someday/ info") + self.assertIn("\x1b[", out) def test_color_error(self): """Error color.""" - code, out, err = self.t.runError('add error priority:X') - self.assertIn('\x1b[34m', err) + code, out, err = self.t.runError("add error priority:X") + self.assertIn("\x1b[34m", err) def test_color_header(self): """Header color.""" - code, out, err = self.t('rc.verbose=header,default /control/') - self.assertIn('\x1b[34m', err) + code, out, err = self.t("rc.verbose=header,default /control/") + self.assertIn("\x1b[34m", err) def test_color_footnote(self): """Footnote color.""" - code, out, err = self.t('rc.verbose=on /control/') - self.assertIn('\x1b[31mConfiguration override', err) + code, out, err = self.t("rc.verbose=on /control/") + self.assertIn("\x1b[31mConfiguration override", err) def test_color_debug(self): """Debug color.""" - code, out, err = self.t('rc.debug=1 /control/') - self.assertIn('\x1b[32mTimer', err) + code, out, err = self.t("rc.debug=1 /control/") + self.assertIn("\x1b[32mTimer", err) def test_project_x(self): """Project x color rule.""" - code, out, err = self.t('/project_x/ info') - self.assertIn('\x1b[31m', out) + code, out, err = self.t("/project_x/ info") + self.assertIn("\x1b[31m", out) def test_project_none(self): """Project none color rule.""" - code, out, err = self.t('/control/ rc.color.project.none=red info') - self.assertIn('\x1b[31m', out) + code, out, err = self.t("/control/ rc.color.project.none=red info") + self.assertIn("\x1b[31m", out) def test_priority_h(self): """Priority H color rule.""" - code, out, err = self.t('/pri_h/ info') - self.assertIn('\x1b[31m', out) + code, out, err = self.t("/pri_h/ info") + self.assertIn("\x1b[31m", out) def test_priority_m(self): """Priority M color rule.""" - code, out, err = self.t('/pri_m/ info') - self.assertIn('\x1b[34m', out) + code, out, err = self.t("/pri_m/ info") + self.assertIn("\x1b[34m", out) def test_priority_l(self): """Priority L color rule.""" - code, out, err = self.t('/pri_l/ info') - self.assertIn('\x1b[32m', out) + code, out, err = self.t("/pri_l/ info") + self.assertIn("\x1b[32m", out) def test_keyword(self): """Keyword color rule.""" - code, out, err = self.t('/keyword/ info') - self.assertIn('\x1b[31m', out) + code, out, err = self.t("/keyword/ info") + self.assertIn("\x1b[31m", out) def test_tag_x(self): """Tag x color rule.""" - code, out, err = self.t('/tag_x/ info') - self.assertIn('\x1b[31m', out) + code, out, err = self.t("/tag_x/ info") + self.assertIn("\x1b[31m", out) def test_tag_none(self): """Tag none color rule.""" - code, out, err = self.t('/control/ rc.color.tag.none=red info') - self.assertIn('\x1b[31m', out) + code, out, err = self.t("/control/ rc.color.tag.none=red info") + self.assertIn("\x1b[31m", out) def test_tagged(self): """Tagged color rule.""" - code, out, err = self.t('/tag_x/ rc.color.tag.x= rc.color.tagged=blue info') - self.assertIn('\x1b[34m', out) + code, out, err = self.t("/tag_x/ rc.color.tag.x= rc.color.tagged=blue info") + self.assertIn("\x1b[34m", out) def test_recurring(self): """Recurring color rule.""" - code, out, err = self.t('/recurring/ info') - self.assertIn('\x1b[31m', out) + code, out, err = self.t("/recurring/ info") + self.assertIn("\x1b[31m", out) def test_uda(self): """UDA color rule.""" - code, out, err = self.t('/uda_xxx_1/ info') - self.assertIn('\x1b[31m', out) + code, out, err = self.t("/uda_xxx_1/ info") + self.assertIn("\x1b[31m", out) def test_uda_value(self): """UDA Value color rule.""" - code, out, err = self.t('/uda_xxx_4/ rc.color.uda.xxx= info') - self.assertIn('\x1b[34m', out) + code, out, err = self.t("/uda_xxx_4/ rc.color.uda.xxx= info") + self.assertIn("\x1b[34m", out) + class TestColorRulesMerging(TestCase): @@ -225,37 +227,48 @@ class TestColorRulesMerging(TestCase): self.t = Task() # Controlling peripheral color. - self.t.config('_forcecolor', 'on') - self.t.config('fontunderline', 'off') # label underlining complicates the tests. - self.t.config('color.alternate', '') # alternating color complicateѕ the tests. - self.t.config('default.command', 'list') + self.t.config("_forcecolor", "on") + self.t.config( + "fontunderline", "off" + ) # label underlining complicates the tests. + self.t.config("color.alternate", "") # alternating color complicateѕ the tests. + self.t.config("default.command", "list") # Color rules. Only due and tagged affect resulting color. - self.t.config('color.due', 'red') - self.t.config('color.tagged','on white') - self.t.config('rule.color.precedence', 'due,tagged') + self.t.config("color.due", "red") + self.t.config("color.tagged", "on white") + self.t.config("rule.color.precedence", "due,tagged") - self.t('add due:tomorrow +home hometask') # Task that matches both color rules + self.t("add due:tomorrow +home hometask") # Task that matches both color rules - @unittest.skipIf('CYGWIN' in platform.system(), 'Skipping color merge test for Cygwin') - @unittest.skipIf('FreeBSD' in platform.system(), 'Skipping color merge test for FREEBSD') + @unittest.skipIf( + "CYGWIN" in platform.system(), "Skipping color merge test for Cygwin" + ) + @unittest.skipIf( + "FreeBSD" in platform.system(), "Skipping color merge test for FREEBSD" + ) def test_colors_merge(self): """Tests whether colors merge""" - code, out, err = self.t('1 info') - self.assertIn('\x1b[31;47mhometask', out) # Red on white + code, out, err = self.t("1 info") + self.assertIn("\x1b[31;47mhometask", out) # Red on white - @unittest.skipIf('CYGWIN' in platform.system(), 'Skipping color merge test for Cygwin') - @unittest.skipIf('FreeBSD' in platform.system(), 'Skipping color merge test for FREEBSD') + @unittest.skipIf( + "CYGWIN" in platform.system(), "Skipping color merge test for Cygwin" + ) + @unittest.skipIf( + "FreeBSD" in platform.system(), "Skipping color merge test for FREEBSD" + ) def test_colors_merge_off(self): """No color merge behaviour with rule.color.merge=no""" - self.t.config('rule.color.merge', 'no') + self.t.config("rule.color.merge", "no") - code, out, err = self.t('1 info') - self.assertIn('\x1b[31mhometask', out) # Red + code, out, err = self.t("1 info") + self.assertIn("\x1b[31mhometask", out) # Red if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/columns.test.py b/test/columns.test.py index 2a7dd6afb..7e839414e 100755 --- a/test/columns.test.py +++ b/test/columns.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -40,7 +41,7 @@ class TestDescriptionFormats(TestCase): """Executed once before any test in the class""" cls.t = Task() cls.t.config("report.xxx.columns", "id,description") - cls.t.config("verbose", "nothing") + cls.t.config("verbose", "nothing") cls.t("add zero") cls.t("add one long description to exceed a certain string size") @@ -65,13 +66,18 @@ class TestDescriptionFormats(TestCase): def test_description_oneline(self): """Verify formatting of 'description.oneline' column""" code, out, err = self.t("xxx rc.report.xxx.columns:id,description.oneline") - self.assertRegex(out, r"one long description to exceed a certain string size \d{4}-\d{2}-\d{2}") + self.assertRegex( + out, + r"one long description to exceed a certain string size \d{4}-\d{2}-\d{2}", + ) self.assertIn("annotation", out) self.assertNotIn("[1]", out) def test_description_truncated(self): """Verify formatting of 'description.truncated' column""" - code, out, err = self.t("xxx rc.detection:off rc.defaultwidth:40 rc.report.xxx.columns:id,description.truncated") + code, out, err = self.t( + "xxx rc.detection:off rc.defaultwidth:40 rc.report.xxx.columns:id,description.truncated" + ) self.assertIn("exceed a c...", out) self.assertNotIn("annotation", out) self.assertNotIn("[1]", out) @@ -84,13 +90,17 @@ class TestDescriptionFormats(TestCase): def test_description_truncated_count(self): """Verify formatting of 'description.truncated_count' column""" - code, out, err = self.t("xxx rc.detection:off rc.defaultwidth:40 rc.report.xxx.columns:id,description.truncated_count") + code, out, err = self.t( + "xxx rc.detection:off rc.defaultwidth:40 rc.report.xxx.columns:id,description.truncated_count" + ) self.assertIn("exceed... [1]", out) self.assertNotIn("annotation", out) def test_description_format_unrecognized(self): """Verify descriptionuuid.donkey formatting fails""" - code, out, err = self.t.runError("xxx rc.report.xxx.columns:id,description.donkey") + code, out, err = self.t.runError( + "xxx rc.report.xxx.columns:id,description.donkey" + ) self.assertEqual(err, "Unrecognized column format 'description.donkey'\n") @@ -100,7 +110,7 @@ class TestUUIDFormats(TestCase): """Executed once before any test in the class""" cls.t = Task() cls.t.config("report.xxx.columns", "id,uuid") - cls.t.config("verbose", "nothing") + cls.t.config("verbose", "nothing") cls.t("add zero") code, out, err = cls.t("_get 1.uuid") @@ -131,7 +141,7 @@ class TestUrgencyFormats(TestCase): """Executed once before any test in the class""" cls.t = Task() cls.t.config("report.xxx.columns", "id,urgency") - cls.t.config("verbose", "nothing") + cls.t.config("verbose", "nothing") cls.t("add one project:A due:yesterday +tag") @@ -161,7 +171,7 @@ class TestIDFormats(TestCase): """Executed once before any test in the class""" cls.t = Task() cls.t.config("report.xxx.columns", "id") - cls.t.config("verbose", "nothing") + cls.t.config("verbose", "nothing") cls.t("add zero") @@ -186,7 +196,7 @@ class TestStatusFormats(TestCase): """Executed once before any test in the class""" cls.t = Task() cls.t.config("report.xxx.columns", "id,status") - cls.t.config("verbose", "nothing") + cls.t.config("verbose", "nothing") cls.t("add zero") cls.t("add one") @@ -231,7 +241,7 @@ class TestRecurringAttributeFormats(TestCase): """Executed once before any test in the class""" cls.t = Task() cls.t.config("report.xxx.columns", "id") - cls.t.config("verbose", "nothing") + cls.t.config("verbose", "nothing") cls.t("add one due:eoy recur:monthly") cls.t("list") @@ -241,22 +251,34 @@ class TestRecurringAttributeFormats(TestCase): def test_recurrence_formats_short(self): """Verify formatting of assorted short recurrence columns""" - code, out, err = self.t("xxx rc.report.xxx.columns:id,status,due,recur.indicator,mask,imask,parent.short") + code, out, err = self.t( + "xxx rc.report.xxx.columns:id,status,due,recur.indicator,mask,imask,parent.short" + ) self.assertRegex(out, r"1\sRecurring\s+\d{4}-\d{2}-\d{2}\s+R\s+-") - self.assertRegex(out, r"2\sPending\s+\d{4}-\d{2}-\d{2}\s+R\s+0\s+[0-9a-fA-F]{8}") + self.assertRegex( + out, r"2\sPending\s+\d{4}-\d{2}-\d{2}\s+R\s+0\s+[0-9a-fA-F]{8}" + ) def test_recurrence_formats_long(self): """Verify formatting of assorted long recurrence columns""" - code, out, err = self.t("xxx rc.report.xxx.columns:id,status,due,recur.duration,mask,imask,parent.long") + code, out, err = self.t( + "xxx rc.report.xxx.columns:id,status,due,recur.duration,mask,imask,parent.long" + ) self.assertRegex(out, r"1\sRecurring\s+\d{4}-\d{2}-\d{2}\s+P30D\s+-") - self.assertRegex(out, r"2\sPending\s+\d{4}-\d{2}-\d{2}\s+P30D\s+0\s+[0-9a-fA-F-]{36}") + self.assertRegex( + out, r"2\sPending\s+\d{4}-\d{2}-\d{2}\s+P30D\s+0\s+[0-9a-fA-F-]{36}" + ) def test_recurrence_format_unrecognized(self): """Verify *.donkey formatting fails""" - code, out, err = self.t.runError("xxx rc.report.xxx.columns:id,status,due,recur.donkey,mask,imask,parent.long") + code, out, err = self.t.runError( + "xxx rc.report.xxx.columns:id,status,due,recur.donkey,mask,imask,parent.long" + ) self.assertEqual(err, "Unrecognized column format 'recur.donkey'\n") - code, out, err = self.t.runError("xxx rc.report.xxx.columns:id,status,due,recur.duration,mask,imask,parent.donkey") + code, out, err = self.t.runError( + "xxx rc.report.xxx.columns:id,status,due,recur.duration,mask,imask,parent.donkey" + ) self.assertEqual(err, "Unrecognized column format 'parent.donkey'\n") @@ -266,7 +288,7 @@ class TestProjectFormats(TestCase): """Executed once before any test in the class""" cls.t = Task() cls.t.config("report.xxx.columns", "id,project,description") - cls.t.config("verbose", "nothing") + cls.t.config("verbose", "nothing") cls.t("add one project:TOP") cls.t("add two project:TOP.MIDDLE") @@ -278,27 +300,33 @@ class TestProjectFormats(TestCase): def test_project_format_full(self): """Verify project.full formatting""" code, out, err = self.t("xxx rc.report.xxx.columns:id,project.full,description") - self.assertRegex(out, r'1\s+TOP\s+one') - self.assertRegex(out, r'2\s+TOP.MIDDLE\s+two') - self.assertRegex(out, r'3\s+TOP.MIDDLE.BOTTOM\s+three') + self.assertRegex(out, r"1\s+TOP\s+one") + self.assertRegex(out, r"2\s+TOP.MIDDLE\s+two") + self.assertRegex(out, r"3\s+TOP.MIDDLE.BOTTOM\s+three") def test_project_format_parent(self): """Verify project.parent formatting""" - code, out, err = self.t("xxx rc.report.xxx.columns:id,project.parent,description") - self.assertRegex(out, r'1\s+TOP\s+one') - self.assertRegex(out, r'2\s+TOP\s+two') - self.assertRegex(out, r'3\s+TOP\s+three') + code, out, err = self.t( + "xxx rc.report.xxx.columns:id,project.parent,description" + ) + self.assertRegex(out, r"1\s+TOP\s+one") + self.assertRegex(out, r"2\s+TOP\s+two") + self.assertRegex(out, r"3\s+TOP\s+three") def test_project_format_indented(self): """Verify project.indented formatting""" - code, out, err = self.t("xxx rc.report.xxx.columns:id,project.indented,description") - self.assertRegex(out, r'1\s+TOP\s+one') - self.assertRegex(out, r'2\s+MIDDLE\s+two') - self.assertRegex(out, r'3\s+BOTTOM\s+three') + code, out, err = self.t( + "xxx rc.report.xxx.columns:id,project.indented,description" + ) + self.assertRegex(out, r"1\s+TOP\s+one") + self.assertRegex(out, r"2\s+MIDDLE\s+two") + self.assertRegex(out, r"3\s+BOTTOM\s+three") def test_project_format_unrecognized(self): """Verify project.donkey formatting fails""" - code, out, err = self.t.runError("xxx rc.report.xxx.columns:id,project.donkey,description") + code, out, err = self.t.runError( + "xxx rc.report.xxx.columns:id,project.donkey,description" + ) self.assertEqual(err, "Unrecognized column format 'project.donkey'\n") @@ -308,28 +336,30 @@ class TestTagsFormats(TestCase): """Executed once before any test in the class""" cls.t = Task() cls.t.config("report.xxx.columns", "id,tags,description") - cls.t.config("verbose", "nothing") + cls.t.config("verbose", "nothing") cls.t("add one +tag1 +tag2") def test_tags_format_list(self): """Verify tags.list formatting""" code, out, err = self.t("xxx rc.report.xxx.columns:id,tags.list") - self.assertRegex(out, r'1\s+tag1\stag2$') + self.assertRegex(out, r"1\s+tag1\stag2$") def test_tags_format_indicator(self): """Verify tags.indicator formatting""" code, out, err = self.t("xxx rc.report.xxx.columns:id,tags.indicator") - self.assertRegex(out, r'1\s+\+$') + self.assertRegex(out, r"1\s+\+$") def test_tags_format_count(self): """Verify tags.count formatting""" code, out, err = self.t("xxx rc.report.xxx.columns:id,tags.count") - self.assertRegex(out, r'1\s+\[2\]$') + self.assertRegex(out, r"1\s+\[2\]$") def test_tags_format_unrecognized(self): """Verify tags.donkey formatting fails""" - code, out, err = self.t.runError("xxx rc.report.xxx.columns:id,tags.donkey,description") + code, out, err = self.t.runError( + "xxx rc.report.xxx.columns:id,tags.donkey,description" + ) self.assertEqual(err, "Unrecognized column format 'tags.donkey'\n") @@ -339,7 +369,7 @@ class TestDateFormats(TestCase): """Executed once before any test in the class""" cls.t = Task() cls.t.config("report.xxx.columns", "id,due") - cls.t.config("verbose", "nothing") + cls.t.config("verbose", "nothing") cls.t("add one due:yesterday") cls.t("add two due:tomorrow") @@ -347,54 +377,56 @@ class TestDateFormats(TestCase): def test_date_format_formatted(self): """Verify due.formatted formatting""" code, out, err = self.t("xxx rc.report.xxx.columns:id,due.formatted") - self.assertRegex(out, r'1\s+\d{4}-\d{2}-\d{2}') - self.assertRegex(out, r'2\s+\d{4}-\d{2}-\d{2}') + self.assertRegex(out, r"1\s+\d{4}-\d{2}-\d{2}") + self.assertRegex(out, r"2\s+\d{4}-\d{2}-\d{2}") def test_date_format_julian(self): """Verify due.julian formatting""" code, out, err = self.t("xxx rc.report.xxx.columns:id,due.julian") - self.assertRegex(out, r'1\s+\d+\.\d+') - self.assertRegex(out, r'2\s+\d+\.\d+') + self.assertRegex(out, r"1\s+\d+\.\d+") + self.assertRegex(out, r"2\s+\d+\.\d+") def test_date_format_epoch(self): """Verify due.epoch formatting""" code, out, err = self.t("xxx rc.report.xxx.columns:id,due.epoch") - self.assertRegex(out, r'1\s+\d{10}') - self.assertRegex(out, r'2\s+\d{10}') + self.assertRegex(out, r"1\s+\d{10}") + self.assertRegex(out, r"2\s+\d{10}") def test_date_format_iso(self): """Verify due.iso formatting""" code, out, err = self.t("xxx rc.report.xxx.columns:id,due.iso") - self.assertRegex(out, r'1\s+\d{8}T\d{6}Z') - self.assertRegex(out, r'2\s+\d{8}T\d{6}Z') + self.assertRegex(out, r"1\s+\d{8}T\d{6}Z") + self.assertRegex(out, r"2\s+\d{8}T\d{6}Z") def test_date_format_age(self): """Verify due.age formatting""" code, out, err = self.t("xxx rc.report.xxx.columns:id,due.age") - self.assertRegex(out, r'1\s+[0-9.]+d') - self.assertRegex(out, r'2\s+-[0-9.]+[hmin]+') + self.assertRegex(out, r"1\s+[0-9.]+d") + self.assertRegex(out, r"2\s+-[0-9.]+[hmin]+") def test_date_format_remaining(self): """Verify due.remaining formatting""" code, out, err = self.t("xxx rc.report.xxx.columns:id,due.remaining") - self.assertRegex(out, r'1') - self.assertRegex(out, r'2\s+\d+\S+') + self.assertRegex(out, r"1") + self.assertRegex(out, r"2\s+\d+\S+") def test_date_format_relative(self): """Verify due.relative formatting""" code, out, err = self.t("xxx rc.report.xxx.columns:id,due.relative") - self.assertRegex(out, r'1\s+-[0-9.]+d') - self.assertRegex(out, r'2\s+[0-9.]+[hmin]+') + self.assertRegex(out, r"1\s+-[0-9.]+d") + self.assertRegex(out, r"2\s+[0-9.]+[hmin]+") def test_date_format_countdown(self): """Verify due.countdown formatting""" code, out, err = self.t("xxx rc.report.xxx.columns:id,due.countdown") - self.assertRegex(out, r'1\s+') - self.assertRegex(out, r'2\s+\d+\S+') + self.assertRegex(out, r"1\s+") + self.assertRegex(out, r"2\s+\d+\S+") def test_date_format_unrecognized(self): """Verify due.donkey formatting fails""" - code, out, err = self.t.runError("xxx rc.report.xxx.columns:id,due.donkey,description") + code, out, err = self.t.runError( + "xxx rc.report.xxx.columns:id,due.donkey,description" + ) self.assertEqual(err, "Unrecognized column format 'due.donkey'\n") @@ -406,9 +438,9 @@ class TestCustomColumns(TestCase): def test_unrecognized_column(self): """verify that using a bogus colum generates an error""" self.t.config("report.foo.description", "DESC") - self.t.config("report.foo.columns", "id,foo,description") - self.t.config("report.foo.sort", "id+") - self.t.config("report.foo.filter", "project:A") + self.t.config("report.foo.columns", "id,foo,description") + self.t.config("report.foo.sort", "id+") + self.t.config("report.foo.filter", "project:A") # Generate the usage screen, and locate the custom report on it. code, out, err = self.t.runError("foo") @@ -420,8 +452,8 @@ class TestUDAFormats(TestCase): def setUpClass(cls): """Executed once before any test in the class""" cls.t = Task() - cls.t.config("report.xxx.columns", "id,priority") - cls.t.config("verbose", "nothing") + cls.t.config("report.xxx.columns", "id,priority") + cls.t.config("verbose", "nothing") cls.t.config("uda.priority.indicator", "P") cls.t("add one priority:H") @@ -429,19 +461,18 @@ class TestUDAFormats(TestCase): def test_uda_format_formatted(self): """Verify priority.default formatting""" code, out, err = self.t("xxx rc.report.xxx.columns:id,priority.default") - self.assertRegex(out, r'1\s+H') + self.assertRegex(out, r"1\s+H") def test_uda_format_indicator(self): """Verify priority.indicator formatting""" code, out, err = self.t("xxx rc.report.xxx.columns:id,priority.indicator") - self.assertRegex(out, r'1\s+P') + self.assertRegex(out, r"1\s+P") def test_uda_format_unrecognized(self): """Verify priority.donkey formatting fails""" code, out, err = self.t.runError("xxx rc.report.xxx.columns:id,priority.donkey") self.assertEqual(err, "Unrecognized column format 'priority.donkey'\n") - """ depends list* 1 2 10 count [3] @@ -450,6 +481,7 @@ depends list* 1 2 10 start active* ✓ """ + class TestFeature1061(TestCase): def setUp(self): """Executed before each test in the class""" @@ -479,6 +511,7 @@ class TestFeature1061(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/commands.test.py b/test/commands.test.py index bed870791..ee2951852 100755 --- a/test/commands.test.py +++ b/test/commands.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -42,19 +43,24 @@ class TestCommands(TestCase): """Verify 'add', 'modify', 'list' dna""" code, out, err = self.t("commands") self.assertRegex(out, r"add\s+operation\s+RW\s+Ctxt\s+Mods\s+Adds a new task") - self.assertRegex(out, r"list\s+report\s+RO\s+ID\s+GC\s+Ctxt\s+Filt\s+Most details of") + self.assertRegex( + out, r"list\s+report\s+RO\s+ID\s+GC\s+Ctxt\s+Filt\s+Most details of" + ) self.assertRegex(out, r"modify\s+operation\s+RW\s+Filt\s+Mods\s+Modifies the") def test_command_dna_color(self): """Verify 'add', 'modify', 'list' dna""" code, out, err = self.t("commands rc._forcecolor:on") self.assertRegex(out, r"add\s+operation\s+RW\s+Ctxt\s+Mods\s+Adds a new task") - self.assertRegex(out, r"list\s+report\s+RO\s+ID\s+GC\s+Ctxt\s+Filt\s+Most details of") + self.assertRegex( + out, r"list\s+report\s+RO\s+ID\s+GC\s+Ctxt\s+Filt\s+Most details of" + ) self.assertRegex(out, r"modify\s+operation\s+RW\s+Filt\s+Mods\s+Modifies the") if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/completed.test.py b/test/completed.test.py index 92799fa99..91f612808 100755 --- a/test/completed.test.py +++ b/test/completed.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -49,13 +50,14 @@ class TestCompleted(TestCase): self.t("2 delete", input="y\n") code, out, err = self.t("completed") - self.assertIn('one', out) - self.assertNotIn('two', out) - self.assertNotIn('three', out) + self.assertIn("one", out) + self.assertNotIn("two", out) + self.assertNotIn("three", out) if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/configuration.test.py b/test/configuration.test.py index a96bee9aa..e4a89e9ce 100755 --- a/test/configuration.test.py +++ b/test/configuration.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -58,8 +59,8 @@ class TestConfiguration(TestCase): def test_config_completion(self): """verify that the '_config' command generates a full list""" code, out, err = self.t("_config") - self.assertIn("_forcecolor", out) # first - self.assertIn("xterm.title", out) # last + self.assertIn("_forcecolor", out) # first + self.assertIn("xterm.title", out) # last def test_config_nothing(self): """Verify error handling with no args""" @@ -94,6 +95,7 @@ class TestBug1475(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/confirmation.test.py b/test/confirmation.test.py index 1c904def7..bf2d23c60 100755 --- a/test/confirmation.test.py +++ b/test/confirmation.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -44,7 +45,7 @@ class TestConfirmation(TestCase): self.t.config("confirmation", "on") # Create some playthings. - for id in range(1,11): + for id in range(1, 11): self.t("add foo") # Test the various forms of "Yes". @@ -87,7 +88,9 @@ class TestBug1438(TestCase): code, out, err = self.t("list") self.assertIn("Sometimes", out) - code, out, err = self.t("rc.confirmation=off rc.recurrence.confirmation=off 2 mod /Sometimes/Everytime/") + code, out, err = self.t( + "rc.confirmation=off rc.recurrence.confirmation=off 2 mod /Sometimes/Everytime/" + ) self.assertIn("Modified 1 task", out) code, out, err = self.t("list") self.assertIn("Everytime", out) @@ -95,6 +98,7 @@ class TestBug1438(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/context.test.py b/test/context.test.py index 2b3661ec2..db5405394 100755 --- a/test/context.test.py +++ b/test/context.test.py @@ -44,186 +44,205 @@ class ContextManagementTest(TestCase): """With confirmation active, prompt if context filter matches no tasks""" self.t.config("confirmation", "on") - code, out, err = self.t.runError('context define work project:Work', input="y\nn\n") + code, out, err = self.t.runError( + "context define work project:Work", input="y\nn\n" + ) self.assertIn("The filter 'project:Work' matches 0 pending tasks.", out) self.assertNotIn("Context 'work' defined", out) # Assert the config contains context definition - self.assertNotIn('context.work=project:Work\n', self.t.taskrc_content) + self.assertNotIn("context.work=project:Work\n", self.t.taskrc_content) def test_context_define(self): """Test simple context definition.""" - code, out, err = self.t('context define work project:Work', input="y\ny\nn\n") + code, out, err = self.t("context define work project:Work", input="y\ny\nn\n") self.assertIn("Context 'work' defined", out) # Assert the config contains read context definition - context_line = 'context.work.read=project:Work\n' + context_line = "context.work.read=project:Work\n" self.assertIn(context_line, self.t.taskrc_content) # Assert that it contains the definition only once self.assertEqual(self.t.taskrc_content.count(context_line), 1) # Assert the config does not contain write context definition - context_line = 'context.work.write=project:Work\n' + context_line = "context.work.write=project:Work\n" self.assertNotIn(context_line, self.t.taskrc_content) # Assert that legacy style was not used # Assert the config contains read context definition - context_line = 'context.work=project:Work\n' + context_line = "context.work=project:Work\n" self.assertNotIn(context_line, self.t.taskrc_content) def test_context_redefine_same_definition(self): """Test re-defining the context with the same definition.""" - self.t('context define work project:Work', input='y\ny\ny\n') - code, out, err = self.t('context define work project:Work', input='y\ny\ny\n') + self.t("context define work project:Work", input="y\ny\ny\n") + code, out, err = self.t("context define work project:Work", input="y\ny\ny\n") self.assertIn("Context 'work' defined (read, write).", out) # Assert the config contains context definition - context_line = 'context.work.read=project:Work\n' + context_line = "context.work.read=project:Work\n" self.assertIn(context_line, self.t.taskrc_content) self.assertEqual(self.t.taskrc_content.count(context_line), 1) - context_line = 'context.work.write=project:Work\n' + context_line = "context.work.write=project:Work\n" self.assertIn(context_line, self.t.taskrc_content) self.assertEqual(self.t.taskrc_content.count(context_line), 1) def test_context_redefine_different_definition(self): """Test re-defining the context with different definition.""" - self.t('context define work project:Work', input='y\ny\ny\n') - code, out, err = self.t('context define work +work', input='y\ny\ny\n') + self.t("context define work project:Work", input="y\ny\ny\n") + code, out, err = self.t("context define work +work", input="y\ny\ny\n") self.assertIn("Context 'work' defined", out) # Assert the config does not contain the old context definition - self.assertNotIn('context.work.read=project:Work\n', self.t.taskrc_content) - self.assertNotIn('context.work.write=project:Work\n', self.t.taskrc_content) + self.assertNotIn("context.work.read=project:Work\n", self.t.taskrc_content) + self.assertNotIn("context.work.write=project:Work\n", self.t.taskrc_content) # Assert the config contains context definition - context_line = 'context.work.read=+work\n' + context_line = "context.work.read=+work\n" self.assertIn(context_line, self.t.taskrc_content) self.assertEqual(self.t.taskrc_content.count(context_line), 1) - context_line = 'context.work.write=+work\n' + context_line = "context.work.write=+work\n" self.assertIn(context_line, self.t.taskrc_content) self.assertEqual(self.t.taskrc_content.count(context_line), 1) def test_context_define_invalid_for_write_due_to_modifier(self): """Test definition of a context that is not a valid write context.""" self.t.config("confirmation", "off") - code, out, err = self.t('context define urgent due.before:today') + code, out, err = self.t("context define urgent due.before:today") self.assertIn("Context 'urgent' defined", out) # Assert the config contains read context definition - context_line = 'context.urgent.read=due.before:today\n' + context_line = "context.urgent.read=due.before:today\n" self.assertIn(context_line, self.t.taskrc_content) # Assert that it contains the definition only once self.assertEqual(self.t.taskrc_content.count(context_line), 1) # Assert the config does not contain write context definition - context_line = 'context.urgent.write=due.before:today\n' + context_line = "context.urgent.write=due.before:today\n" self.assertNotIn(context_line, self.t.taskrc_content) # Assert that the write context was not set at all - self.assertNotIn('context.urgent.write=', self.t.taskrc_content) + self.assertNotIn("context.urgent.write=", self.t.taskrc_content) # Assert that legacy style was not used # Assert the config contains read context definition - context_line = 'context.urgent=due.before:today\n' + context_line = "context.urgent=due.before:today\n" self.assertNotIn(context_line, self.t.taskrc_content) def test_context_define_invalid_for_write_due_to_operator(self): """Test definition of a context that is not a valid write context because it uses an OR operator.""" self.t.config("confirmation", "off") - code, out, err = self.t('context define urgent due:today or +next') + code, out, err = self.t("context define urgent due:today or +next") self.assertIn("Context 'urgent' defined", out) # Assert the config contains read context definition - context_line = 'context.urgent.read=due:today or +next\n' + context_line = "context.urgent.read=due:today or +next\n" self.assertIn(context_line, self.t.taskrc_content) # Assert that it contains the definition only once self.assertEqual(self.t.taskrc_content.count(context_line), 1) # Assert the config does not contain write context definition - context_line = 'context.urgent.write=due:today or +next\n' + context_line = "context.urgent.write=due:today or +next\n" self.assertNotIn(context_line, self.t.taskrc_content) # Assert that the write context was not set at all - self.assertNotIn('context.urgent.write=', self.t.taskrc_content) + self.assertNotIn("context.urgent.write=", self.t.taskrc_content) # Assert that legacy style was not used # Assert the config contains read context definition - context_line = 'context.urgent=due:today or +next\n' + context_line = "context.urgent=due:today or +next\n" self.assertNotIn(context_line, self.t.taskrc_content) def test_context_define_invalid_for_write_due_to_tag_exclusion(self): """Test definition of a context that is not a valid write context because it contains a tag exclusion.""" self.t.config("confirmation", "off") - code, out, err = self.t('context define nowork due:today -work') + code, out, err = self.t("context define nowork due:today -work") self.assertIn("Context 'nowork' defined", out) # Assert the config contains read context definition - context_line = 'context.nowork.read=due:today -work\n' + context_line = "context.nowork.read=due:today -work\n" self.assertIn(context_line, self.t.taskrc_content) # Assert that it contains the definition only once self.assertEqual(self.t.taskrc_content.count(context_line), 1) # Assert the config does not contain write context definition - context_line = 'context.nowork.write=due:today -work\n' + context_line = "context.nowork.write=due:today -work\n" self.assertNotIn(context_line, self.t.taskrc_content) # Assert that the write context was not set at all - self.assertNotIn('context.nowork.write=', self.t.taskrc_content) + self.assertNotIn("context.nowork.write=", self.t.taskrc_content) # Assert that legacy style was not used # Assert the config contains read context definition - context_line = 'context.nowork=due:today -work\n' + context_line = "context.nowork=due:today -work\n" self.assertNotIn(context_line, self.t.taskrc_content) def test_context_delete(self): """Test simple context deletion.""" - self.t('context define work project:Work', input='y\ny\n') - code, out, err = self.t('context delete work', input='y\ny\n') + self.t("context define work project:Work", input="y\ny\n") + code, out, err = self.t("context delete work", input="y\ny\n") self.assertIn("Context 'work' deleted.", out) # Assert that taskrc does not countain context work definition - self.assertFalse(any('context.work' in line for line in self.t.taskrc_content)) + self.assertFalse(any("context.work" in line for line in self.t.taskrc_content)) def test_context_delete_undefined(self): """Test deletion of undefined context.""" - code, out, err = self.t.runError('context delete foo', input='y\n') + code, out, err = self.t.runError("context delete foo", input="y\n") self.assertIn("Context 'foo' not found.", err) # Assert that taskrc does not countain context work definition - self.assertFalse(any('context.foo.read=' in line for line in self.t.taskrc_content)) - self.assertFalse(any('context.foo.write=' in line for line in self.t.taskrc_content)) + self.assertFalse( + any("context.foo.read=" in line for line in self.t.taskrc_content) + ) + self.assertFalse( + any("context.foo.write=" in line for line in self.t.taskrc_content) + ) def test_context_delete_unset_after_removal(self): """Test that context is unset if its definition has been removed.""" - self.t('context define work project:Work', input='y\ny\n') - self.t('context work') - code, out, err = self.t('context delete work', input='y\ny\n') + self.t("context define work project:Work", input="y\ny\n") + self.t("context work") + code, out, err = self.t("context delete work", input="y\ny\n") self.assertIn("Context 'work' deleted.", out) # Assert that taskrc does not countain context work definition - self.assertFalse(any('context.work=' in line for line in self.t.taskrc_content)) - self.assertFalse(any('context.work.read=' in line for line in self.t.taskrc_content)) - self.assertFalse(any('context.work.write=' in line for line in self.t.taskrc_content)) + self.assertFalse(any("context.work=" in line for line in self.t.taskrc_content)) + self.assertFalse( + any("context.work.read=" in line for line in self.t.taskrc_content) + ) + self.assertFalse( + any("context.work.write=" in line for line in self.t.taskrc_content) + ) # Aseert that the context is not set - code, out, err = self.t('context show') - self.assertIn('No context is currently applied.', out) - self.assertFalse(any(re.search(r"^context(\.(read|write))?=", line) for line in self.t.taskrc_content)) + code, out, err = self.t("context show") + self.assertIn("No context is currently applied.", out) + self.assertFalse( + any( + re.search(r"^context(\.(read|write))?=", line) + for line in self.t.taskrc_content + ) + ) def test_context_list_active(self): """Test the 'context list' command.""" - self.t('context define work project:Work', input='y\ny\n') - self.t('context define home +home', input='y\ny\n') - self.t('context home') - code, out, err = self.t('context list') - contains_work = lambda line: 'work' in line and 'project:Work' in line and 'no' in line - contains_home = lambda line: 'home' in line and '+home' in line and 'yes' in line + self.t("context define work project:Work", input="y\ny\n") + self.t("context define home +home", input="y\ny\n") + self.t("context home") + code, out, err = self.t("context list") + contains_work = ( + lambda line: "work" in line and "project:Work" in line and "no" in line + ) + contains_home = ( + lambda line: "home" in line and "+home" in line and "yes" in line + ) # Assert that output contains work and home context definitions exactly # once @@ -232,39 +251,41 @@ class ContextManagementTest(TestCase): def test_context_list_legacy(self): """Test the determination of legacy context definition.""" - self.t('config context.old project:Old', input='y\n') - self.t('context old') - code, out, err = self.t('context list') + self.t("config context.old project:Old", input="y\n") + self.t("context old") + code, out, err = self.t("context list") # Assert that "old" context has only the read component defined - self.assertRegex(out, r'read\s+project:Old\s+yes') - self.assertRegex(out, r'write\s+yes') + self.assertRegex(out, r"read\s+project:Old\s+yes") + self.assertRegex(out, r"write\s+yes") def test_context_initially_empty(self): """Test that no context is set initially.""" - self.t('context define work project:Work', input='y\ny\n') - self.t('context define home +home', input='y\ny\n') + self.t("context define work project:Work", input="y\ny\n") + self.t("context define home +home", input="y\ny\n") - code, out, err = self.t('context show') - self.assertIn('No context is currently applied.', out) - self.assertFalse(any(re.search("^context=", line) for line in self.t.taskrc_content)) + code, out, err = self.t("context show") + self.assertIn("No context is currently applied.", out) + self.assertFalse( + any(re.search("^context=", line) for line in self.t.taskrc_content) + ) def test_context_setting(self): """Test simple context setting.""" - self.t('context define work project:Work', input='y\ny\n') - self.t('context define home home', input='y\ny\n') + self.t("context define work project:Work", input="y\ny\n") + self.t("context define home home", input="y\ny\n") - code, out, err = self.t('context home') + code, out, err = self.t("context home") self.assertIn("Context 'home' set.", out) self.assertIn("context=home\n", self.t.taskrc_content) def test_context_resetting(self): """Test resetting the same context.""" - self.t('context define work project:Work', input='y\ny\n') - self.t('context define home +home', input='y\ny\n') + self.t("context define work project:Work", input="y\ny\n") + self.t("context define home +home", input="y\ny\n") - self.t('context home') - code, out, err = self.t('context home') + self.t("context home") + code, out, err = self.t("context home") self.assertIn("Context 'home' set.", out) context_line = "context=home\n" @@ -272,92 +293,98 @@ class ContextManagementTest(TestCase): def test_context_switching(self): """Test changing the context.""" - self.t('context define work project:Work', input='y\ny\n') - self.t('context define home +home', input='y\ny\n') + self.t("context define work project:Work", input="y\ny\n") + self.t("context define home +home", input="y\ny\n") # Switch to home context - code, out, err = self.t('context home') + code, out, err = self.t("context home") self.assertIn("Context 'home' set.", out) self.assertEqual(self.t.taskrc_content.count("context=home\n"), 1) # Switch to work context - code, out, err = self.t('context work') + code, out, err = self.t("context work") self.assertIn("Context 'work' set.", out) self.assertNotIn("context=home\n", self.t.taskrc_content) self.assertEqual(self.t.taskrc_content.count("context=work\n"), 1) # Switch back to home context - code, out, err = self.t('context home') + code, out, err = self.t("context home") self.assertIn("Context 'home' set.", out) self.assertNotIn("context=work\n", self.t.taskrc_content) self.assertEqual(self.t.taskrc_content.count("context=home\n"), 1) def test_context_unsetting(self): """Test removing the context.""" - self.t('context define work project:Work', input='y\ny\n') - self.t('context define home +home', input='y\ny\n') + self.t("context define work project:Work", input="y\ny\n") + self.t("context define home +home", input="y\ny\n") - self.t('context home') - code, out, err = self.t('context none') + self.t("context home") + code, out, err = self.t("context none") # Assert expected output. self.assertIn("Context unset.", out) # Assert no context definition in the taskrc - contains_any_context = lambda line: re.match('^context=', line) - self.assertFalse(any(contains_any_context(line) for line in self.t.taskrc_content)) + contains_any_context = lambda line: re.match("^context=", line) + self.assertFalse( + any(contains_any_context(line) for line in self.t.taskrc_content) + ) # Assert no context showing up using show subcommand - code, out, err = self.t('context show') + code, out, err = self.t("context show") self.assertIn("No context is currently applied.", out) def test_context_unsetting_after_switching(self): """Test unsetting the context after changing the context around.""" - self.t('context define work project:Work', input='y\ny\n') - self.t('context define home +home', input='y\ny\n') + self.t("context define work project:Work", input="y\ny\n") + self.t("context define home +home", input="y\ny\n") # Switch to contexts around - self.t('context home') - self.t('context work') - self.t('context home') + self.t("context home") + self.t("context work") + self.t("context home") # Unset the context - code, out, err = self.t('context none') + code, out, err = self.t("context none") # Assert expected output. self.assertIn("Context unset.", out) # Assert no context definition in the taskrc - contains_any_context = lambda line: re.match('^context=', line) - self.assertFalse(any(contains_any_context(line) for line in self.t.taskrc_content)) + contains_any_context = lambda line: re.match("^context=", line) + self.assertFalse( + any(contains_any_context(line) for line in self.t.taskrc_content) + ) # Assert no context showing up using show subcommand - code, out, err = self.t('context show') + code, out, err = self.t("context show") self.assertIn("No context is currently applied.", out) def test_context_unsetting_with_no_context_set(self): """Test removing the context when no context is set.""" - self.t('context define work project:Work', input='y\ny\n') - self.t('context define home +home', input='y\ny\n') + self.t("context define work project:Work", input="y\ny\n") + self.t("context define home +home", input="y\ny\n") - code, out, err = self.t.runError('context none') + code, out, err = self.t.runError("context none") # Assert expected output. self.assertIn("Context not unset.", err) # Assert no context definition in the taskrc - contains_any_context = lambda line: re.match('^context=', line) - self.assertFalse(any(contains_any_context(line) for line in self.t.taskrc_content)) + contains_any_context = lambda line: re.match("^context=", line) + self.assertFalse( + any(contains_any_context(line) for line in self.t.taskrc_content) + ) # Assert no context showing up using show subcommand - code, out, err = self.t('context show') + code, out, err = self.t("context show") self.assertIn("No context is currently applied.", out) def test_context(self): """Test the _context command.""" - self.t('context define work project:Work', input='y\ny\n') - self.t('context define home +home', input='y\ny\n') - code, out, err = self.t('_context') + self.t("context define work project:Work", input="y\ny\n") + self.t("context define home +home", input="y\ny\n") + code, out, err = self.t("_context") # Assert expected output. self.assertIn("work", out.splitlines()) @@ -366,12 +393,12 @@ class ContextManagementTest(TestCase): def test_context_completion(self): """Test the _context command with some context set.""" - self.t('context define work project:Work', input='y\ny\n') - self.t('context define home +home', input='y\ny\n') + self.t("context define work project:Work", input="y\ny\n") + self.t("context define home +home", input="y\ny\n") # Activate some context - self.t('context work') - code, out, err = self.t('_context') + self.t("context work") + code, out, err = self.t("_context") # Assert expected output. self.assertIn("work", out.splitlines()) @@ -386,9 +413,9 @@ class ContextEvaluationTest(TestCase): self.t.config("confirmation", "off") # Setup contexts - self.t('context define work project:Work') - self.t('context define home +home') - self.t('context define today due:today') + self.t("context define work project:Work") + self.t("context define home +home") + self.t("context define today due:today") # Setup tasks self.t('add project:Work "work task"') @@ -398,7 +425,7 @@ class ContextEvaluationTest(TestCase): def test_context_evaluation(self): """Test the context applied with report list command.""" - code, out, err = self.t('list') + code, out, err = self.t("list") # Assert all the tasks are present in the output self.assertIn("work task", out) @@ -407,8 +434,8 @@ class ContextEvaluationTest(TestCase): self.assertIn("home today task", out) # Set the home context and rerun the report - self.t('context home') - code, out, err = self.t('list') + self.t("context home") + code, out, err = self.t("list") # Assert all the tasks with the home tag are present in the output self.assertNotIn("work task", out) @@ -418,7 +445,7 @@ class ContextEvaluationTest(TestCase): def test_context_evaluation_switching(self): """Test swtiching context using the list report.""" - code, out, err = self.t('list') + code, out, err = self.t("list") # Assert all the tasks are present in the output self.assertIn("work task", out) @@ -427,8 +454,8 @@ class ContextEvaluationTest(TestCase): self.assertIn("home today task", out) # Set the home context and rerun the report - self.t('context home') - code, out, err = self.t('list') + self.t("context home") + code, out, err = self.t("list") # Assert all the tasks with the home tag are present in the output self.assertNotIn("work task", out) @@ -437,8 +464,8 @@ class ContextEvaluationTest(TestCase): self.assertIn("home today task", out) # Set the work context and rerun the report - self.t('context work') - code, out, err = self.t('list') + self.t("context work") + code, out, err = self.t("list") # Assert all the tasks with the home tag are present in the output self.assertIn("work task", out) @@ -447,8 +474,8 @@ class ContextEvaluationTest(TestCase): self.assertNotIn("home today task", out) # Set the today context and rerun the report - self.t('context today') - code, out, err = self.t('list') + self.t("context today") + code, out, err = self.t("list") # Assert all the tasks with the home tag are present in the output self.assertNotIn("work task", out) @@ -458,8 +485,8 @@ class ContextEvaluationTest(TestCase): def test_context_evaluation_unset(self): """Test unsetting context with report list command.""" - self.t('context home') - code, out, err = self.t('list') + self.t("context home") + code, out, err = self.t("list") # Assert all the tasks home tagged tasks are present self.assertNotIn("work task", out) @@ -468,8 +495,8 @@ class ContextEvaluationTest(TestCase): self.assertIn("home today task", out) # Set the context to none - self.t('context none') - code, out, err = self.t('list') + self.t("context none") + code, out, err = self.t("list") # Assert all the tasks are present in the output self.assertIn("work task", out) @@ -481,8 +508,8 @@ class ContextEvaluationTest(TestCase): """Test the context applied with report list command combined with user filters.""" # Set the home context - self.t('context home') - code, out, err = self.t('list due:today') + self.t("context home") + code, out, err = self.t("list due:today") # Assert all the tasks are present in the output self.assertNotIn("work task", out) @@ -491,8 +518,8 @@ class ContextEvaluationTest(TestCase): self.assertIn("home today task", out) # Set the work context and rerun the report - self.t('context work') - code, out, err = self.t('list due:today') + self.t("context work") + code, out, err = self.t("list due:today") # Assert all the tasks are present in the output self.assertNotIn("work task", out) @@ -506,10 +533,10 @@ class ContextEvaluationTest(TestCase): filters are used. """ - self.t('context home') + self.t("context home") # Try task not included in context - output = self.t('1 list')[1] + output = self.t("1 list")[1] # Assert that ID filter works even if it does not match the context self.assertIn("work task", output) @@ -518,7 +545,7 @@ class ContextEvaluationTest(TestCase): self.assertNotIn("home today task", output) # Try task included in context - output = self.t('2 list')[1] + output = self.t("2 list")[1] # Assert that ID filter works if it does match # the context (sanity check) @@ -528,7 +555,7 @@ class ContextEvaluationTest(TestCase): self.assertNotIn("home today task", output) # Test for combination of IDs - output = self.t('1 2 list')[1] + output = self.t("1 2 list")[1] # Assert that ID filter works if it partly matches # and partly does not match the context @@ -543,12 +570,12 @@ class ContextEvaluationTest(TestCase): filters are used. """ - self.t('context home') - first_uuid = self.t('_get 1.uuid')[1] - second_uuid = self.t('_get 2.uuid')[1] + self.t("context home") + first_uuid = self.t("_get 1.uuid")[1] + second_uuid = self.t("_get 2.uuid")[1] # Try task not included in context - output = self.t('%s list' % first_uuid)[1] + output = self.t("%s list" % first_uuid)[1] # Assert that UUID filter works even if it does not match # the context @@ -558,7 +585,7 @@ class ContextEvaluationTest(TestCase): self.assertNotIn("home today task", output) # Try task included in context - output = self.t('%s list' % second_uuid)[1] + output = self.t("%s list" % second_uuid)[1] # Assert that UUID filter works if it does match # the context (sanity check) @@ -568,7 +595,7 @@ class ContextEvaluationTest(TestCase): self.assertNotIn("home today task", output) # Test for combination of UUIDs - output = self.t('%s %s list' % (first_uuid, second_uuid))[1] + output = self.t("%s %s list" % (first_uuid, second_uuid))[1] # Assert that UUID filter works if it partly matches # and partly does not match the context @@ -585,7 +612,7 @@ class ContextEvaluationTest(TestCase): self.t.config("report.list.context", "0") # Get the tasks - code, out, err = self.t('list') + code, out, err = self.t("list") # Assert all the tasks are present in the output self.assertIn("work task", out) @@ -594,9 +621,9 @@ class ContextEvaluationTest(TestCase): self.assertIn("home today task", out) # Set the home context and rerun the report - self.t('context home') + self.t("context home") - code, out, err = self.t('list') + code, out, err = self.t("list") # Assert nothing changed - all the tasks are present in the output self.assertIn("work task", out) @@ -643,7 +670,10 @@ class ContextErrorHandling(TestCase): """Verify 'task context show' with contexts works""" self.t.config("confirmation", "off") code, out, err = self.t("context define work +work") - self.assertIn("Context 'work' defined (read, write). Use 'task context work' to activate.", out) + self.assertIn( + "Context 'work' defined (read, write). Use 'task context work' to activate.", + out, + ) code, out, err = self.t("context work") self.assertIn("Context 'work' set. Use 'task context none' to remove.", out) @@ -660,6 +690,7 @@ class ContextErrorHandling(TestCase): code, out, err = self.t("context show") self.assertIn("No context is currently applied.", out) + class TestBug1734(TestCase): def setUp(self): self.t = Task() @@ -679,6 +710,7 @@ class TestBug1734(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python syntax=python diff --git a/test/count.test.py b/test/count.test.py index 3cd712d30..d3f6969ed 100755 --- a/test/count.test.py +++ b/test/count.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -56,6 +57,7 @@ class TestCount(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/custom.config.test.py b/test/custom.config.test.py index 329c0f516..5124802b2 100755 --- a/test/custom.config.test.py +++ b/test/custom.config.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -41,10 +42,12 @@ class TestCustomConfig(TestCase): self.t.config("alias.xyzzyx", "status:waiting") self.t.config("imnotrecognized", "kai") - self.DIFFER_MSG = ("Some of your .taskrc variables differ from the " - "default values.") - self.NOT_RECOG_MSG = ("Your .taskrc file contains these unrecognized " - "variables:") + self.DIFFER_MSG = ( + "Some of your .taskrc variables differ from the " "default values." + ) + self.NOT_RECOG_MSG = ( + "Your .taskrc file contains these unrecognized " "variables:" + ) def test_show_alias(self): """task show - warns when non-default values are matched @@ -89,6 +92,7 @@ class TestCustomConfig(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/custom.recur_ind.test.py b/test/custom.recur_ind.test.py index d0084cdae..a1a11e696 100755 --- a/test/custom.recur_ind.test.py +++ b/test/custom.recur_ind.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -41,26 +42,27 @@ class TestCustomRecurIndicator(TestCase): def test_recurrence_indicator(self): """Add a recurring and non-recurring task, look for the indicator.""" - self.t.config("report.foo.columns", "id,recur.indicator") - self.t.config("report.foo.labels", "ID,R") - self.t.config("report.foo.sort", "id+") - self.t.config("verbose", "nothing") + self.t.config("report.foo.columns", "id,recur.indicator") + self.t.config("report.foo.labels", "ID,R") + self.t.config("report.foo.sort", "id+") + self.t.config("verbose", "nothing") self.t("add foo due:tomorrow recur:weekly") self.t("add bar") code, out, err = self.t("foo") self.assertIn(" 1 R", out) - self.assertIn(" 2", out) + self.assertIn(" 2", out) self.assertIn(" 3 R", out) code, out, err = self.t("foo rc.recurrence.indicator=RE") self.assertIn(" 1 RE", out) - self.assertIn(" 2", out) + self.assertIn(" 2", out) self.assertIn(" 3 RE", out) if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/custom.tag_ind.test.py b/test/custom.tag_ind.test.py index ae24bf9a4..2c67897a9 100755 --- a/test/custom.tag_ind.test.py +++ b/test/custom.tag_ind.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -40,9 +41,9 @@ class TestCustomTagIndicator(TestCase): """Executed once before any test in the class""" cls.t = Task() cls.t.config("report.foo.description", "DESC") - cls.t.config("report.foo.columns", "id,tags.indicator") - cls.t.config("report.foo.labels", "ID,T") - cls.t.config("report.foo.sort", "id+") + cls.t.config("report.foo.columns", "id,tags.indicator") + cls.t.config("report.foo.labels", "ID,T") + cls.t.config("report.foo.sort", "id+") cls.t("add foo +tag") cls.t("add bar") @@ -61,6 +62,7 @@ class TestCustomTagIndicator(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/custom.test.py b/test/custom.test.py index bc839e37a..bf7a194ff 100755 --- a/test/custom.test.py +++ b/test/custom.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -39,10 +40,10 @@ class TestCustomReports(TestCase): """Executed before each test in the class""" self.t = Task() self.t.config("report.foo.description", "DESC") - self.t.config("report.foo.labels", "ID,DESCRIPTION") - self.t.config("report.foo.columns", "id,description") - self.t.config("report.foo.sort", "id+") - self.t.config("report.foo.filter", "project:A") + self.t.config("report.foo.labels", "ID,DESCRIPTION") + self.t.config("report.foo.columns", "id,description") + self.t.config("report.foo.sort", "id+") + self.t.config("report.foo.filter", "project:A") def test_custom_report_help(self): """Verify custom report description is shown in help""" @@ -72,19 +73,23 @@ class TestCustomReports(TestCase): code, out, err = self.t("foo rc._forcecolor:on rc.report.foo.filter:") self.assertIn("[44m", out) + class TestCustomErrorHandling(TestCase): def setUp(self): self.t = Task() def test_size_mismatch(self): self.t.config("report.foo.columns", "id,description") - self.t.config("report.foo.labels", "id") + self.t.config("report.foo.labels", "id") code, out, err = self.t.runError("foo") - self.assertIn("There are different numbers of columns and labels for report 'foo'.", err) + self.assertIn( + "There are different numbers of columns and labels for report 'foo'.", err + ) if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/date.iso.test.py b/test/date.iso.test.py index ca656b7a3..41999314e 100755 --- a/test/date.iso.test.py +++ b/test/date.iso.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -60,6 +61,7 @@ class TestDateISOAndEpoch(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/dateformat.test.py b/test/dateformat.test.py index 60c46470d..3a1ffd41e 100755 --- a/test/dateformat.test.py +++ b/test/dateformat.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -40,8 +41,8 @@ class TestDateformat(TestCase): """Executed once before any test in the class""" cls.t = Task() cls.t.config("report.xxx.columns", "id,due") - cls.t.config("report.xxx.labels", "ID,DUE") - cls.t.config("report.xxx.sort", "id") + cls.t.config("report.xxx.labels", "ID,DUE") + cls.t.config("report.xxx.sort", "id") def setUp(self): """Executed before each test in the class""" @@ -55,6 +56,7 @@ class TestDateformat(TestCase): code, out, err = self.t("xxx rc.dateformat:YMDTHNS") self.assertEqual(out.count("20150704T000000"), 3) + class TestBug886(TestCase): def setUp(self): """Executed before each test in the class""" @@ -63,12 +65,12 @@ class TestBug886(TestCase): def test_invalid_day(self): """886: Test invalid day synonym - Bug 886: tw doesn't warn the user if, e.g., a weekday cannot be resolved properly + Bug 886: tw doesn't warn the user if, e.g., a weekday cannot be resolved properly """ - code, out, err =self.t("add one due:sun") + code, out, err = self.t("add one due:sun") self.assertIn("Created task 1.", out) - code, out, err =self.t.runError("add two due:donkey") + code, out, err = self.t.runError("add two due:donkey") self.assertIn("'donkey' is not a valid date", err) @@ -79,33 +81,36 @@ class TestBug986(TestCase): def test_dateformat_precedence(self): """986: Verify rc.dateformat.info takes precedence over rc.dateformat""" - self.t('add test') - self.t('1 start') + self.t("add test") + self.t("1 start") - code, out, err = self.t('1 info rc.dateformat:XX rc.dateformat.info:__') - self.assertIn('__', out) - self.assertNotIn('XX', out) + code, out, err = self.t("1 info rc.dateformat:XX rc.dateformat.info:__") + self.assertIn("__", out) + self.assertNotIn("XX", out) - code, out, err = self.t('1 info rc.dateformat:__ rc.dateformat.info:') - self.assertIn('__', out) + code, out, err = self.t("1 info rc.dateformat:__ rc.dateformat.info:") + self.assertIn("__", out) class TestBug1620(TestCase): def setUp(self): """Executed before each test in the class""" self.t = Task() - self.t.config('dateformat', 'YMD-HN') + self.t.config("dateformat", "YMD-HN") def test_dateformat_overrides_iso(self): """1620: Verify that a defined dateformat overrides the ISO interpretation""" - code, out, err = self.t ('add pro:vorhaben due:20150601-1415 tatusmeeting vorbereiten') + code, out, err = self.t( + "add pro:vorhaben due:20150601-1415 tatusmeeting vorbereiten" + ) - code, out, err = self.t ('_get 1.due') + code, out, err = self.t("_get 1.due") self.assertEqual(out, "2015-06-01T14:15:00\n") - code, out, err = self.t ('long') + code, out, err = self.t("long") self.assertIn("20150601-1415", out) + class TestCapitalizedDays(TestCase): """Make sure capitalized names such as 'Friday' work. @@ -124,28 +129,30 @@ class TestCapitalizedDays(TestCase): def test_dateformat_capitalized(self): """Verify upper case days and months work""" # Lower case: - code, out, err = self.t('add sometask due:mon') - code, out, err = self.t('add sometask due:monday') - code, out, err = self.t('add sometask due:jan') - code, out, err = self.t('add sometask due:january') + code, out, err = self.t("add sometask due:mon") + code, out, err = self.t("add sometask due:monday") + code, out, err = self.t("add sometask due:jan") + code, out, err = self.t("add sometask due:january") # Upper case days of the week - code, out, err = self.t('add sometask due:Tue') - code, out, err = self.t('add sometask due:Tuesday') - code, out, err = self.t('add sometask due:Thu') - code, out, err = self.t('add sometask due:Thursday') + code, out, err = self.t("add sometask due:Tue") + code, out, err = self.t("add sometask due:Tuesday") + code, out, err = self.t("add sometask due:Thu") + code, out, err = self.t("add sometask due:Thursday") # Upper case months: - code, out, err = self.t('add sometask due:Jan') - code, out, err = self.t('add sometask due:January') - code, out, err = self.t('add sometask due:Jun') - code, out, err = self.t('add sometask due:June') - code, out, err = self.t('add sometask due:May') + code, out, err = self.t("add sometask due:Jan") + code, out, err = self.t("add sometask due:January") + code, out, err = self.t("add sometask due:Jun") + code, out, err = self.t("add sometask due:June") + code, out, err = self.t("add sometask due:May") # Incorrect: - code, out, err = self.t.runError('add sometask due:Yo') - code, out, err = self.t.runError('add sometask due:TU') + code, out, err = self.t.runError("add sometask due:Yo") + code, out, err = self.t.runError("add sometask due:TU") + if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/datesort.test.py b/test/datesort.test.py index 5f270cb37..81712ad89 100755 --- a/test/datesort.test.py +++ b/test/datesort.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -41,13 +42,13 @@ class TestDateSort(TestCase): def test_datesort(self): """Verify dates sort properly with a report date format that hides date details""" - self.t.config("verbose", "nothing") - self.t.config("dateformat", "YMD") - self.t.config("report.small_list.columns", "due,description") - self.t.config("report.small_list.labels", "Due,Description") - self.t.config("report.small_list.sort", "due+") - self.t.config("report.small_list.filter", "status:pending") - self.t.config("report.small_list.dateformat", "D") + self.t.config("verbose", "nothing") + self.t.config("dateformat", "YMD") + self.t.config("report.small_list.columns", "due,description") + self.t.config("report.small_list.labels", "Due,Description") + self.t.config("report.small_list.sort", "due+") + self.t.config("report.small_list.filter", "status:pending") + self.t.config("report.small_list.dateformat", "D") self.t("add one due:20150101") self.t("add two due:20150201") @@ -65,6 +66,7 @@ class TestDateSort(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/datetime-negative.test.py b/test/datetime-negative.test.py index 8dfc258a4..5d80639c9 100755 --- a/test/datetime-negative.test.py +++ b/test/datetime-negative.test.py @@ -44,10 +44,10 @@ class BaseDateTimeNegativeTest(TestCase): self.t = Task() def assertInvalidDatetimeFormat(self, value): - self.t.runError('add due:{0} test1'.format(value)) - self.t.runError('add scheduled:{0} test2'.format(value)) - self.t.runError('add wait:{0} test3'.format(value)) - self.t.runError('add until:{0} test4'.format(value)) + self.t.runError("add due:{0} test1".format(value)) + self.t.runError("add scheduled:{0} test2".format(value)) + self.t.runError("add wait:{0} test3".format(value)) + self.t.runError("add until:{0} test4".format(value)) class TestIncorrectDate(BaseDateTimeNegativeTest): @@ -58,60 +58,60 @@ class TestIncorrectDate(BaseDateTimeNegativeTest): """ def test_set_incorrect_datetime_randomstring(self): - self.assertInvalidDatetimeFormat('random') + self.assertInvalidDatetimeFormat("random") @unittest.skip # see #2996 def test_set_incorrect_datetime_negative_in_YYYY_MM_DD(self): - self.assertInvalidDatetimeFormat('-2014-07-07') + self.assertInvalidDatetimeFormat("-2014-07-07") def test_set_incorrect_datetime_missing_day_in_YYYY_MM_DD(self): - self.assertInvalidDatetimeFormat('2014-07-') + self.assertInvalidDatetimeFormat("2014-07-") def test_set_incorrect_datetime_month_zero_in_YYYY_MM_DD(self): - self.assertInvalidDatetimeFormat('2014-0-12') + self.assertInvalidDatetimeFormat("2014-0-12") def test_set_incorrect_datetime_invalid_characters_in_YYYY_MM_DD(self): - self.assertInvalidDatetimeFormat('abcd-ab-ab') + self.assertInvalidDatetimeFormat("abcd-ab-ab") def test_set_incorrect_datetime_day_as_zeros_in_YYYY_DDD(self): - self.assertInvalidDatetimeFormat('2014-000') + self.assertInvalidDatetimeFormat("2014-000") def test_set_incorrect_datetime_overlap_day_in_nonoverlap_year_in_YYYY_DDD(self): - self.assertInvalidDatetimeFormat('2014-366') + self.assertInvalidDatetimeFormat("2014-366") def test_set_incorrect_datetime_medium_overlap_day_in_YYYY_DDD(self): - self.assertInvalidDatetimeFormat('2014-999') + self.assertInvalidDatetimeFormat("2014-999") def test_set_incorrect_datetime_huge_overlap_day_in_YYYY_DDD(self): - self.assertInvalidDatetimeFormat('2014-999999999') + self.assertInvalidDatetimeFormat("2014-999999999") def test_set_incorrect_datetime_week_with_the_number_zero_in_YYYY_Www(self): - self.assertInvalidDatetimeFormat('2014-W00') + self.assertInvalidDatetimeFormat("2014-W00") def test_set_incorrect_datetime_overflow_in_week_in_YYYY_Www(self): - self.assertInvalidDatetimeFormat('2014-W54') + self.assertInvalidDatetimeFormat("2014-W54") # Unsupported non-extended form. def test_set_incorrect_datetime_day_zero_in_YYYY_WwwD(self): - self.assertInvalidDatetimeFormat('2014-W240') + self.assertInvalidDatetimeFormat("2014-W240") # Unsupported non-extended form. def test_set_incorrect_datetime_day_eight_in_YYYY_WwwD(self): - self.assertInvalidDatetimeFormat('2014-W248') + self.assertInvalidDatetimeFormat("2014-W248") # Unsupported non-extended form. def test_set_incorrect_datetime_day_two_hundred_in_YYYY_WwwD(self): - self.assertInvalidDatetimeFormat('2014-W24200') + self.assertInvalidDatetimeFormat("2014-W24200") # Disabled: Looks like 'hhmm-hh' - #def test_set_incorrect_datetime_month_zero_in_YYYY_MM(self): + # def test_set_incorrect_datetime_month_zero_in_YYYY_MM(self): # self.assertInvalidDatetimeFormat('2014-00') def test_set_incorrect_datetime_overflow_month_in_YYYY_MM(self): - self.assertInvalidDatetimeFormat('2014-13') + self.assertInvalidDatetimeFormat("2014-13") def test_set_incorrect_datetime_huge_overflow_month_in_YYYY_MM(self): - self.assertInvalidDatetimeFormat('2014-99') + self.assertInvalidDatetimeFormat("2014-99") class TestIncorrectTime(BaseDateTimeNegativeTest): @@ -121,276 +121,276 @@ class TestIncorrectTime(BaseDateTimeNegativeTest): """ def test_set_incorrect_datetime_hour_overflow_in_hh_mm(self): - self.assertInvalidDatetimeFormat('25:00') + self.assertInvalidDatetimeFormat("25:00") def test_set_incorrect_datetime_huge_hour_overflow_in_hh_mm(self): - self.assertInvalidDatetimeFormat('99:00') + self.assertInvalidDatetimeFormat("99:00") def test_set_incorrect_datetime_minute_overflow_in_hh_mm(self): - self.assertInvalidDatetimeFormat('12:60') + self.assertInvalidDatetimeFormat("12:60") def test_set_incorrect_datetime_huge_minute_overflow_in_hh_mm(self): - self.assertInvalidDatetimeFormat('12:99') + self.assertInvalidDatetimeFormat("12:99") def test_set_incorrect_datetime_invalid_minutes_in_hh_mm(self): - self.assertInvalidDatetimeFormat('12:ab') + self.assertInvalidDatetimeFormat("12:ab") def test_set_incorrect_datetime_invalid_hours_in_hh_mm(self): - self.assertInvalidDatetimeFormat('ab:12') + self.assertInvalidDatetimeFormat("ab:12") def test_set_incorrect_datetime_invalid_time_in_hh_mm(self): - self.assertInvalidDatetimeFormat('ab:cd') + self.assertInvalidDatetimeFormat("ab:cd") @unittest.skip # see #2996 def test_set_incorrect_datetime_negative_hours_in_hh_mm(self): - self.assertInvalidDatetimeFormat('-12:12') + self.assertInvalidDatetimeFormat("-12:12") def test_set_incorrect_datetime_negative_minutes_in_hh_mm(self): - self.assertInvalidDatetimeFormat('12:-12') + self.assertInvalidDatetimeFormat("12:-12") def test_set_incorrect_datetime_hour_overflow_in_hh_mmZ(self): - self.assertInvalidDatetimeFormat('25:00Z') + self.assertInvalidDatetimeFormat("25:00Z") def test_set_incorrect_datetime_huge_hour_overflow_in_hh_mmZ(self): - self.assertInvalidDatetimeFormat('99:00Z') + self.assertInvalidDatetimeFormat("99:00Z") def test_set_incorrect_datetime_minute_overflow_in_hh_mmZ(self): - self.assertInvalidDatetimeFormat('12:60Z') + self.assertInvalidDatetimeFormat("12:60Z") def test_set_incorrect_datetime_huge_minute_overflow_in_hh_mmZ(self): - self.assertInvalidDatetimeFormat('12:99Z') + self.assertInvalidDatetimeFormat("12:99Z") def test_set_incorrect_datetime_invalid_minutes_in_hh_mmZ(self): - self.assertInvalidDatetimeFormat('12:abZ') + self.assertInvalidDatetimeFormat("12:abZ") def test_set_incorrect_datetime_invalid_hours_in_hh_mmZ(self): - self.assertInvalidDatetimeFormat('ab:12Z') + self.assertInvalidDatetimeFormat("ab:12Z") def test_set_incorrect_datetime_invalid_time_in_hh_mmZ(self): - self.assertInvalidDatetimeFormat('ab:cdZ') + self.assertInvalidDatetimeFormat("ab:cdZ") @unittest.skip # see #2996 def test_set_incorrect_datetime_negative_hours_in_hh_mmZ(self): - self.assertInvalidDatetimeFormat('-12:12Z') + self.assertInvalidDatetimeFormat("-12:12Z") def test_set_incorrect_datetime_negative_minutes_in_hh_mmZ(self): - self.assertInvalidDatetimeFormat('12:-12Z') + self.assertInvalidDatetimeFormat("12:-12Z") def test_set_incorrect_datetime_hour_overflow_in_hh_mm_plus_hh_mm(self): - self.assertInvalidDatetimeFormat('25:00+01:00') + self.assertInvalidDatetimeFormat("25:00+01:00") def test_set_incorrect_datetime_huge_hour_overflow_in_hh_mm_plus_hh_mm(self): - self.assertInvalidDatetimeFormat('99:00+01:00') + self.assertInvalidDatetimeFormat("99:00+01:00") def test_set_incorrect_datetime_minute_overflow_in_hh_mm_plus_hh_mm(self): - self.assertInvalidDatetimeFormat('12:60+01:00') + self.assertInvalidDatetimeFormat("12:60+01:00") def test_set_incorrect_datetime_huge_minute_overflow_in_hh_mm_plus_hh_mm(self): - self.assertInvalidDatetimeFormat('12:99+01:00') + self.assertInvalidDatetimeFormat("12:99+01:00") def test_set_incorrect_datetime_invalid_minutes_in_hh_mm_plus_hh_mm(self): - self.assertInvalidDatetimeFormat('12:ab+01:00') + self.assertInvalidDatetimeFormat("12:ab+01:00") def test_set_incorrect_datetime_invalid_hours_in_hh_mm_plus_hh_mm(self): - self.assertInvalidDatetimeFormat('ab:12+01:00') + self.assertInvalidDatetimeFormat("ab:12+01:00") def test_set_incorrect_datetime_invalid_time_in_hh_mm_plus_hh_mm(self): - self.assertInvalidDatetimeFormat('ab:cd+01:00') + self.assertInvalidDatetimeFormat("ab:cd+01:00") @unittest.skip # see #2996 def test_set_incorrect_datetime_negative_hours_in_hh_mm_plus_hh_mm(self): - self.assertInvalidDatetimeFormat('-12:12+01:00') + self.assertInvalidDatetimeFormat("-12:12+01:00") def test_set_incorrect_datetime_negative_minutes_in_hh_mm_plus_hh_mm(self): - self.assertInvalidDatetimeFormat('12:-12+01:00') + self.assertInvalidDatetimeFormat("12:-12+01:00") def test_set_incorrect_datetime_hour_overflow_in_hh_mm_minus_hh_mm(self): - self.assertInvalidDatetimeFormat('25:00-01:00') + self.assertInvalidDatetimeFormat("25:00-01:00") def test_set_incorrect_datetime_huge_hour_overflow_in_hh_mm_minus_hh_mm(self): - self.assertInvalidDatetimeFormat('99:00-01:00') + self.assertInvalidDatetimeFormat("99:00-01:00") def test_set_incorrect_datetime_minute_overflow_in_hh_mm_minus_hh_mm(self): - self.assertInvalidDatetimeFormat('12:60-01:00') + self.assertInvalidDatetimeFormat("12:60-01:00") def test_set_incorrect_datetime_huge_minute_overflow_in_hh_mm_minus_hh_mm(self): - self.assertInvalidDatetimeFormat('12:99-01:00') + self.assertInvalidDatetimeFormat("12:99-01:00") def test_set_incorrect_datetime_invalid_minutes_in_hh_mm_minus_hh_mm(self): - self.assertInvalidDatetimeFormat('12:ab-01:00') + self.assertInvalidDatetimeFormat("12:ab-01:00") def test_set_incorrect_datetime_invalid_hours_in_hh_mm_minus_hh_mm(self): - self.assertInvalidDatetimeFormat('ab:12-01:00') + self.assertInvalidDatetimeFormat("ab:12-01:00") def test_set_incorrect_datetime_invalid_time_in_hh_mm_minus_hh_mm(self): - self.assertInvalidDatetimeFormat('ab:cd-01:00') + self.assertInvalidDatetimeFormat("ab:cd-01:00") @unittest.skip # see #2996 def test_set_incorrect_datetime_negative_hours_in_hh_mm_minus_hh_mm(self): - self.assertInvalidDatetimeFormat('-12:12-01:00') + self.assertInvalidDatetimeFormat("-12:12-01:00") def test_set_incorrect_datetime_negative_minutes_in_hh_mm_minus_hh_mm(self): - self.assertInvalidDatetimeFormat('12:-12-01:00') + self.assertInvalidDatetimeFormat("12:-12-01:00") def test_set_incorrect_datetime_hour_overflow_in_hh_mm_ss(self): - self.assertInvalidDatetimeFormat('25:00:00') + self.assertInvalidDatetimeFormat("25:00:00") def test_set_incorrect_datetime_huge_hour_overflow_in_hh_mm_ss(self): - self.assertInvalidDatetimeFormat('99:00:00') + self.assertInvalidDatetimeFormat("99:00:00") def test_set_incorrect_datetime_minute_overflow_in_hh_mm_ss(self): - self.assertInvalidDatetimeFormat('12:60:00') + self.assertInvalidDatetimeFormat("12:60:00") def test_set_incorrect_datetime_huge_minute_overflow_in_hh_mm_ss(self): - self.assertInvalidDatetimeFormat('12:99:00') + self.assertInvalidDatetimeFormat("12:99:00") def test_set_incorrect_datetime_second_overflow_in_hh_mm_ss(self): - self.assertInvalidDatetimeFormat('12:12:60') + self.assertInvalidDatetimeFormat("12:12:60") def test_set_incorrect_datetime_huge_second_overflow_in_hh_mm_ss(self): - self.assertInvalidDatetimeFormat('12:12:99') + self.assertInvalidDatetimeFormat("12:12:99") def test_set_incorrect_datetime_invalid_minutes_in_hh_mm_ss(self): - self.assertInvalidDatetimeFormat('12:ab:00') + self.assertInvalidDatetimeFormat("12:ab:00") def test_set_incorrect_datetime_invalid_hours_in_hh_mm_ss(self): - self.assertInvalidDatetimeFormat('ab:12:00') + self.assertInvalidDatetimeFormat("ab:12:00") def test_set_incorrect_datetime_invalid_seconds_in_hh_mm_ss(self): - self.assertInvalidDatetimeFormat('12:12:ab') + self.assertInvalidDatetimeFormat("12:12:ab") def test_set_incorrect_datetime_invalid_time_in_hh_mm_ss(self): - self.assertInvalidDatetimeFormat('ab:cd:ef') + self.assertInvalidDatetimeFormat("ab:cd:ef") @unittest.skip # see #2996 def test_set_incorrect_datetime_negative_hours_in_hh_mm_ss(self): - self.assertInvalidDatetimeFormat('-12:12:12') + self.assertInvalidDatetimeFormat("-12:12:12") def test_set_incorrect_datetime_negative_minutes_in_hh_mm_ss(self): - self.assertInvalidDatetimeFormat('12:-12:12') + self.assertInvalidDatetimeFormat("12:-12:12") def test_set_incorrect_datetime_negative_seconds_in_hh_mm_ss(self): - self.assertInvalidDatetimeFormat('12:12:-12') + self.assertInvalidDatetimeFormat("12:12:-12") def test_set_incorrect_datetime_hour_overflow_in_hh_mm_ssZ(self): - self.assertInvalidDatetimeFormat('25:00:00Z') + self.assertInvalidDatetimeFormat("25:00:00Z") def test_set_incorrect_datetime_huge_hour_overflow_in_hh_mm_ssZ(self): - self.assertInvalidDatetimeFormat('99:00:00Z') + self.assertInvalidDatetimeFormat("99:00:00Z") def test_set_incorrect_datetime_minute_overflow_in_hh_mm_ssZ(self): - self.assertInvalidDatetimeFormat('12:60:00Z') + self.assertInvalidDatetimeFormat("12:60:00Z") def test_set_incorrect_datetime_huge_minute_overflow_in_hh_mm_ssZ(self): - self.assertInvalidDatetimeFormat('12:99:00Z') + self.assertInvalidDatetimeFormat("12:99:00Z") def test_set_incorrect_datetime_second_overflow_in_hh_mm_ssZ(self): - self.assertInvalidDatetimeFormat('12:12:60Z') + self.assertInvalidDatetimeFormat("12:12:60Z") def test_set_incorrect_datetime_huge_second_overflow_in_hh_mm_ssZ(self): - self.assertInvalidDatetimeFormat('12:12:99Z') + self.assertInvalidDatetimeFormat("12:12:99Z") def test_set_incorrect_datetime_invalid_minutes_in_hh_mm_ssZ(self): - self.assertInvalidDatetimeFormat('12:ab:00Z') + self.assertInvalidDatetimeFormat("12:ab:00Z") def test_set_incorrect_datetime_invalid_hours_in_hh_mm_ssZ(self): - self.assertInvalidDatetimeFormat('ab:12:00Z') + self.assertInvalidDatetimeFormat("ab:12:00Z") def test_set_incorrect_datetime_invalid_seconds_in_hh_mm_ssZ(self): - self.assertInvalidDatetimeFormat('12:12:abZ') + self.assertInvalidDatetimeFormat("12:12:abZ") def test_set_incorrect_datetime_invalid_time_in_hh_mm_ssZ(self): - self.assertInvalidDatetimeFormat('ab:cd:efZ') + self.assertInvalidDatetimeFormat("ab:cd:efZ") @unittest.skip # see #2996 def test_set_incorrect_datetime_negative_hours_in_hh_mm_ssZ(self): - self.assertInvalidDatetimeFormat('-12:12:12Z') + self.assertInvalidDatetimeFormat("-12:12:12Z") def test_set_incorrect_datetime_negative_minutes_in_hh_mm_ssZ(self): - self.assertInvalidDatetimeFormat('12:-12:12Z') + self.assertInvalidDatetimeFormat("12:-12:12Z") def test_set_incorrect_datetime_negative_seconds_in_hh_mm_ssZ(self): - self.assertInvalidDatetimeFormat('12:12:-12Z') + self.assertInvalidDatetimeFormat("12:12:-12Z") def test_set_incorrect_datetime_hour_overflow_in_hh_mm_ss_plus_hh_mm(self): - self.assertInvalidDatetimeFormat('25:00:00+01:00') + self.assertInvalidDatetimeFormat("25:00:00+01:00") def test_set_incorrect_datetime_huge_hour_overflow_in_hh_mm_ss_plus_hh_mm(self): - self.assertInvalidDatetimeFormat('95:00:00+01:00') + self.assertInvalidDatetimeFormat("95:00:00+01:00") def test_set_incorrect_datetime_minute_overflow_in_hh_mm_ss_plus_hh_mm(self): - self.assertInvalidDatetimeFormat('12:60:00+01:00') + self.assertInvalidDatetimeFormat("12:60:00+01:00") def test_set_incorrect_datetime_huge_minute_overflow_in_hh_mm_ss_plus_hh_mm(self): - self.assertInvalidDatetimeFormat('12:99:00+01:00') + self.assertInvalidDatetimeFormat("12:99:00+01:00") def test_set_incorrect_datetime_second_overflow_in_hh_mm_ss_plus_hh_mm(self): - self.assertInvalidDatetimeFormat('12:12:60+01:00') + self.assertInvalidDatetimeFormat("12:12:60+01:00") def test_set_incorrect_datetime_huge_second_overflow_in_hh_mm_ss_plus_hh_mm(self): - self.assertInvalidDatetimeFormat('12:12:99+01:00') + self.assertInvalidDatetimeFormat("12:12:99+01:00") def test_set_incorrect_datetime_invalid_minutes_in_hh_mm_ss_plus_hh_mm(self): - self.assertInvalidDatetimeFormat('12:ab:00+01:00') + self.assertInvalidDatetimeFormat("12:ab:00+01:00") def test_set_incorrect_datetime_invalid_hours_in_hh_mm_ss_plus_hh_mm(self): - self.assertInvalidDatetimeFormat('ab:12:00+01:00') + self.assertInvalidDatetimeFormat("ab:12:00+01:00") def test_set_incorrect_datetime_invalid_seconds_in_hh_mm_ss_plus_hh_mm(self): - self.assertInvalidDatetimeFormat('12:12:ab+01:00') + self.assertInvalidDatetimeFormat("12:12:ab+01:00") def test_set_incorrect_datetime_invalid_time_in_hh_mm_ss_plus_hh_mm(self): - self.assertInvalidDatetimeFormat('ab:cd:ef+01:00') + self.assertInvalidDatetimeFormat("ab:cd:ef+01:00") @unittest.skip # see #2996 def test_set_incorrect_datetime_negative_hours_in_hh_mm_ss_plus_hh_mm(self): - self.assertInvalidDatetimeFormat('-12:12:12+01:00') + self.assertInvalidDatetimeFormat("-12:12:12+01:00") def test_set_incorrect_datetime_negative_minutes_in_hh_mm_ss_plus_hh_mm(self): - self.assertInvalidDatetimeFormat('12:-12:12+01:00') + self.assertInvalidDatetimeFormat("12:-12:12+01:00") def test_set_incorrect_datetime_negative_seconds_in_hh_mm_ss_plus_hh_mm(self): - self.assertInvalidDatetimeFormat('12:12:-12+01:00') + self.assertInvalidDatetimeFormat("12:12:-12+01:00") def test_set_incorrect_datetime_hour_overflow_in_hh_mm_ss_minus_hh_mm(self): - self.assertInvalidDatetimeFormat('25:00:00-01:00') + self.assertInvalidDatetimeFormat("25:00:00-01:00") def test_set_incorrect_datetime_huge_hour_overflow_in_hh_mm_ss_minus_hh_mm(self): - self.assertInvalidDatetimeFormat('95:00:00-01:00') + self.assertInvalidDatetimeFormat("95:00:00-01:00") def test_set_incorrect_datetime_minute_overflow_in_hh_mm_ss_minus_hh_mm(self): - self.assertInvalidDatetimeFormat('12:60:00-01:00') + self.assertInvalidDatetimeFormat("12:60:00-01:00") def test_set_incorrect_datetime_huge_minute_overflow_in_hh_mm_ss_minus_hh_mm(self): - self.assertInvalidDatetimeFormat('12:99:00-01:00') + self.assertInvalidDatetimeFormat("12:99:00-01:00") def test_set_incorrect_datetime_second_overflow_in_hh_mm_ss_minus_hh_mm(self): - self.assertInvalidDatetimeFormat('12:12:60-01:00') + self.assertInvalidDatetimeFormat("12:12:60-01:00") def test_set_incorrect_datetime_huge_second_overflow_in_hh_mm_ss_minus_hh_mm(self): - self.assertInvalidDatetimeFormat('12:12:99-01:00') + self.assertInvalidDatetimeFormat("12:12:99-01:00") def test_set_incorrect_datetime_invalid_minutes_in_hh_mm_ss_minus_hh_mm(self): - self.assertInvalidDatetimeFormat('12:ab:00-01:00') + self.assertInvalidDatetimeFormat("12:ab:00-01:00") def test_set_incorrect_datetime_invalid_hours_in_hh_mm_ss_minus_hh_mm(self): - self.assertInvalidDatetimeFormat('ab:12:00-01:00') + self.assertInvalidDatetimeFormat("ab:12:00-01:00") def test_set_incorrect_datetime_invalid_seconds_in_hh_mm_ss_minus_hh_mm(self): - self.assertInvalidDatetimeFormat('12:12:ab-01:00') + self.assertInvalidDatetimeFormat("12:12:ab-01:00") def test_set_incorrect_datetime_invalid_time_in_hh_mm_ss_minus_hh_mm(self): - self.assertInvalidDatetimeFormat('ab:cd:ef-01:00') + self.assertInvalidDatetimeFormat("ab:cd:ef-01:00") @unittest.skip # see #2996 def test_set_incorrect_datetime_negative_hours_in_hh_mm_ss_minus_hh_mm(self): - self.assertInvalidDatetimeFormat('-12:12:12-01:00') + self.assertInvalidDatetimeFormat("-12:12:12-01:00") def test_set_incorrect_datetime_negative_minutes_in_hh_mm_ss_minus_hh_mm(self): - self.assertInvalidDatetimeFormat('12:-12:12-01:00') + self.assertInvalidDatetimeFormat("12:-12:12-01:00") def test_set_incorrect_datetime_negative_seconds_in_hh_mm_ss_minus_hh_mm(self): - self.assertInvalidDatetimeFormat('12:12:-12-01:00') + self.assertInvalidDatetimeFormat("12:12:-12-01:00") # There were a group of tests that failed for the wrong reason, and these # have been removed. @@ -434,8 +434,10 @@ class TestIncorrectTime(BaseDateTimeNegativeTest): # 12:12+03:2 # 12:12+3:2 + if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/debug.test.py b/test/debug.test.py index 2f4c70467..1838a51d9 100755 --- a/test/debug.test.py +++ b/test/debug.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -87,6 +88,7 @@ class TestDebugMode(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/default.test.py b/test/default.test.py index 5bab560b6..8afdf91f5 100755 --- a/test/default.test.py +++ b/test/default.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -40,8 +41,8 @@ class TestCMD(TestCase): cls.t = Task() cls.t.config("default.command", "list") - cls.t('add one') - cls.t('add two') + cls.t("add one") + cls.t("add two") def test_default_command(self): """default command""" @@ -51,8 +52,8 @@ class TestCMD(TestCase): def test_info_command(self): """info command""" - code, out, err = self.t('1') - self.assertRegex(out, r'Description\s+one') + code, out, err = self.t("1") + self.assertRegex(out, r"Description\s+one") class TestDefaults(TestCase): @@ -60,11 +61,11 @@ class TestDefaults(TestCase): def setUpClass(cls): """Executed once before any test in the class""" cls.t = Task() - cls.t.config("default.command", "list") - cls.t.config("default.project", "PROJECT") + cls.t.config("default.command", "list") + cls.t.config("default.project", "PROJECT") cls.t.config("uda.priority.default", "M") - cls.t.config("default.due", "eom") - cls.t.config("default.scheduled", "eom") + cls.t.config("default.due", "eom") + cls.t.config("default.scheduled", "eom") def test_all_defaults(self): """Verify all defaults are employed""" @@ -125,6 +126,7 @@ class TestBug1377(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/delete.test.py b/test/delete.test.py index bc998724d..29953559c 100755 --- a/test/delete.test.py +++ b/test/delete.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -46,7 +47,7 @@ class TestDelete(TestCase): uuid = out.strip() self.t("1 delete", input="y\n") - self.t.runError("list") # GC/handleRecurrence + self.t.runError("list") # GC/handleRecurrence code, out, err = self.t("_get 1.status") self.assertEqual("\n", out) @@ -77,7 +78,7 @@ class TestDelete(TestCase): code, out, err = self.t("1 done") self.assertIn("Completed 1 task.", out) - self.t("all") # GC/handleRecurrence + self.t("all") # GC/handleRecurrence code, out, err = self.t("%s delete" % uuid, input="y\n") self.assertIn("Deleted 1 task.", out) @@ -141,6 +142,7 @@ class TestDelete(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/denotate.test.py b/test/denotate.test.py index 341346434..50b81f773 100755 --- a/test/denotate.test.py +++ b/test/denotate.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -68,7 +69,9 @@ class TestDenotate(TestCase): # Failed partial match, one annotation code, out, err = self.t.runError("rc.search.case.sensitive=yes 2 denotate AL") - self.assertIn("Did not find any matching annotation to be deleted for 'AL'.", out) + self.assertIn( + "Did not find any matching annotation to be deleted for 'AL'.", out + ) # Exact match, two annotations code, out, err = self.t("1 denotate beta") @@ -91,6 +94,7 @@ class TestDenotate(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/dependencies.test.py b/test/dependencies.test.py index 971cf34a1..e9a6bc307 100755 --- a/test/dependencies.test.py +++ b/test/dependencies.test.py @@ -29,6 +29,7 @@ import string import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -81,9 +82,9 @@ class TestDependencies(TestCase): def test_circular_5(self): """Check circular dependencies are caught, using 5 tasks""" - self.t("add three") - self.t("add four") - self.t("add five") + self.t("add three") + self.t("add four") + self.t("add five") self.t("5 modify dep:4") self.t("4 modify dep:3") self.t("3 modify dep:2") @@ -116,9 +117,9 @@ class TestDependencies(TestCase): def test_modify_multiple(self): """Check circular dependencies are caught, using 5 tasks""" - self.t("add three") - self.t("add four") - self.t("add five") + self.t("add three") + self.t("add four") + self.t("add five") code, out, err = self.t("1 modify dep:2,3,4") self.assertIn("Modified 1 task.", out) @@ -235,18 +236,18 @@ class TestBug697(TestCase): def test_blocking_to_recurring(self): """697: Verify that making a blocking task into a recurring task breaks dependencies - Bug 697: Making a blocking task recur breaks dependency. - 1. Create 2 tasks: "foo" and "bar". - 2. Give "bar" a due date. - 3. Make "foo" depend on "bar". - 4. Make "bar" recur yearly. + Bug 697: Making a blocking task recur breaks dependency. + 1. Create 2 tasks: "foo" and "bar". + 2. Give "bar" a due date. + 3. Make "foo" depend on "bar". + 4. Make "bar" recur yearly. """ self.t("add one") self.t("add two") self.t("2 modify due:eom") self.t("1 modify depends:2") self.t("2 modify recur:yearly") - self.t("list") # GC/handleRecurrence + self.t("list") # GC/handleRecurrence # The problem is that although 1 --> 2, 2 is now a recurring parent, and as 1 # depends on the parent UUID, it is not something transferred to the child on @@ -332,21 +333,21 @@ class TestFeature725(TestCase): class Test1481(TestCase): def setUp(self): self.t = Task() - self.t('add parent') - self.t('add child') - self.t('add child2') - self.child1_uuid = self.t.export_one(2)['uuid'] - self.child2_uuid = self.t.export_one(3)['uuid'] + self.t("add parent") + self.t("add child") + self.t("add child2") + self.child1_uuid = self.t.export_one(2)["uuid"] + self.child2_uuid = self.t.export_one(3)["uuid"] def test_set_dependency_on_first_completed_task(self): """1481: Sets dependency on task which has been just completed.""" - self.t('2 done') + self.t("2 done") # Trigger the GC to clear up IDs - self.t('next') + self.t("next") # Set the dependency - self.t('1 modify depends:%s' % self.child1_uuid) + self.t("1 modify depends:%s" % self.child1_uuid) def test_set_dependency_on_second_completed_task(self): """ @@ -354,26 +355,25 @@ class Test1481(TestCase): before most recently completed task. """ - self.t('2 done') - self.t('3 done') + self.t("2 done") + self.t("3 done") # Trigger the GC to clear up IDs - self.t('next') + self.t("next") # Set the dependencies - self.t('1 modify depends:%s' % self.child2_uuid) + self.t("1 modify depends:%s" % self.child2_uuid) def test_set_dependency_on_two_completed_tasks(self): - """ 1481: Sets dependency on two most recent completed tasks. """ - self.t('2 done') - self.t('3 done') + """1481: Sets dependency on two most recent completed tasks.""" + self.t("2 done") + self.t("3 done") # Trigger the GC to clear up IDs - self.t('next') + self.t("next") # Set the dependencies - self.t('1 modify depends:%s,%s' % (self.child1_uuid, - self.child2_uuid)) + self.t("1 modify depends:%s,%s" % (self.child1_uuid, self.child2_uuid)) # TODO - test dependency.confirmation config variable @@ -385,6 +385,7 @@ class Test1481(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/diag.test.py b/test/diag.test.py index 60aab3c39..1c9a824a8 100755 --- a/test/diag.test.py +++ b/test/diag.test.py @@ -29,6 +29,7 @@ import sys import os import platform import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -38,11 +39,11 @@ from basetest import Task, TestCase class TestDiagnostics(TestCase): def setUp(self): self.t = Task() - self.t.config("editor", "edlin") + self.t.config("editor", "edlin") @unittest.skipIf( - getattr(platform, 'dist', None) == None or 'xenial' == platform.dist()[-1], - 'Skipping diagnostics test on Ubuntu 16.04, as it lacks full C++17 support' + getattr(platform, "dist", None) == None or "xenial" == platform.dist()[-1], + "Skipping diagnostics test on Ubuntu 16.04, as it lacks full C++17 support", ) def test_diagnostics(self): """Task diag output, so we can monitor platforms""" @@ -60,6 +61,7 @@ class TestDiagnostics(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/diag_color.test.py b/test/diag_color.test.py index edbf069ee..c82305e78 100755 --- a/test/diag_color.test.py +++ b/test/diag_color.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -69,6 +70,7 @@ class TestDiagColor(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/dom.test.cpp b/test/dom.test.cpp index 34a815476..2a031e835 100644 --- a/test/dom.test.cpp +++ b/test/dom.test.cpp @@ -27,31 +27,23 @@ #include // cmake.h include header must come first -#include #include #include +#include //////////////////////////////////////////////////////////////////////////////// -bool providerString (const std::string& path, Variant& var) -{ - if (path == "name") - { - var = Variant ("value"); +bool providerString(const std::string& path, Variant& var) { + if (path == "name") { + var = Variant("value"); return true; - } - else if (path == "name.next") - { - var = Variant ("value.next"); + } else if (path == "name.next") { + var = Variant("value.next"); return true; - } - else if (path == "foo") - { - var = Variant ("bar"); + } else if (path == "foo") { + var = Variant("bar"); return true; - } - else if (path == "name.size") - { - var = Variant (6); + } else if (path == "name.size") { + var = Variant(6); return true; } @@ -59,40 +51,39 @@ bool providerString (const std::string& path, Variant& var) } //////////////////////////////////////////////////////////////////////////////// -int main (int, char**) -{ - UnitTest t (12); +int main(int, char**) { + UnitTest t(12); DOM dom; - t.is (dom.count (), 0, "DOM empty count is zero"); + t.is(dom.count(), 0, "DOM empty count is zero"); - dom.addSource ("name", &providerString); - dom.addSource ("name.next", &providerString); - dom.addSource ("name.size", &providerString); - dom.addSource ("foo", &providerString); - t.diag (dom.dump ()); - t.is (dom.count (), 4, "DOM now contains 4 nodes"); + dom.addSource("name", &providerString); + dom.addSource("name.next", &providerString); + dom.addSource("name.size", &providerString); + dom.addSource("foo", &providerString); + t.diag(dom.dump()); + t.is(dom.count(), 4, "DOM now contains 4 nodes"); - t.ok (dom.valid ("name"), "DOM 'name' valid"); - t.ok (dom.valid ("name.next"), "DOM 'name.next' valid"); - t.ok (dom.valid ("name.size"), "DOM 'name.size' valid"); - t.ok (dom.valid ("foo"), "DOM 'foo' valid"); - t.notok (dom.valid ("missing"), "DOM 'missing' not valid"); + t.ok(dom.valid("name"), "DOM 'name' valid"); + t.ok(dom.valid("name.next"), "DOM 'name.next' valid"); + t.ok(dom.valid("name.size"), "DOM 'name.size' valid"); + t.ok(dom.valid("foo"), "DOM 'foo' valid"); + t.notok(dom.valid("missing"), "DOM 'missing' not valid"); - auto v = dom.get ("name"); - t.is (v.get_string (), "value", "DOM get 'name' --> 'value'"); + auto v = dom.get("name"); + t.is(v.get_string(), "value", "DOM get 'name' --> 'value'"); - v = dom.get ("name.next"); - t.is (v.get_string (), "value.next", "DOM get 'name.next' --> 'value.next'"); + v = dom.get("name.next"); + t.is(v.get_string(), "value.next", "DOM get 'name.next' --> 'value.next'"); - v = dom.get ("name.size"); - t.is (v.get_integer (), 6, "DOM get 'name.size' --> 6"); + v = dom.get("name.size"); + t.is(v.get_integer(), 6, "DOM get 'name.size' --> 6"); - v = dom.get ("foo"); - t.is (v.get_string (), "bar", "DOM get 'name.size' --> 6"); + v = dom.get("foo"); + t.is(v.get_string(), "bar", "DOM get 'name.size' --> 6"); - v = dom.get ("missing"); - t.is (v.get_string (), "", "DOM get 'missing' --> ''"); + v = dom.get("missing"); + t.is(v.get_string(), "", "DOM get 'missing' --> ''"); return 0; } diff --git a/test/dom2.test.py b/test/dom2.test.py index 85025c0f0..0cd2403c0 100755 --- a/test/dom2.test.py +++ b/test/dom2.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -52,199 +53,201 @@ class TestDOM(TestCase): cls.t("3 annotate note") # Add task containing UDA attributes - cls.t("add ticket task " - "ticketdate:2015-09-04 " - "ticketest:hour " - "ticketnote:comment " - "ticketnum:47") + cls.t( + "add ticket task " + "ticketdate:2015-09-04 " + "ticketest:hour " + "ticketnote:comment " + "ticketnum:47" + ) def test_dom_no_ref(self): - """ DOM missing reference """ + """DOM missing reference""" code, out, err = self.t.runError("_get") self.assertEqual("No DOM reference specified.\n", err) def test_dom_bad_ref(self): - """ DOM bad reference """ + """DOM bad reference""" code, out, err = self.t.runError("_get donkey") self.assertEqual("'donkey' is not a DOM reference.\n", err) def test_dom_task_ref(self): - """ DOM reference to other task """ + """DOM reference to other task""" code, out, err = self.t("_get 2.due") self.assertIn("2011-09-01T00:00:00", out) def test_dom_cli_ref(self): - """ DOM reference to current command line """ + """DOM reference to current command line""" code, out, err = self.t("_get 3.wait") self.assertIn("2011-09-01T00:00:00", out) def test_dom_id_uuid_roundtrip(self): - """ DOM id/uuid roundtrip """ + """DOM id/uuid roundtrip""" code, out, err = self.t("_get 1.uuid") uuid = out.strip() code, out, err = self.t("_get {0}.id".format(uuid)) self.assertEqual("1\n", out) def test_dom_fail(self): - """ DOM lookup of missing item """ + """DOM lookup of missing item""" code, out, err = self.t("_get 5.description") self.assertEqual("\n", out) def test_dom_tags(self): - """ DOM 3.tags """ + """DOM 3.tags""" code, out, err = self.t("_get 3.tags") self.assertEqual("tag1,tag2\n", out) def test_dom_tags_tag1(self): - """ DOM 3.tags.tag1 """ + """DOM 3.tags.tag1""" code, out, err = self.t("_get 3.tags.tag1") self.assertEqual("tag1\n", out) def test_dom_tags_OVERDUE(self): - """ DOM 3.tags.OVERDUE """ + """DOM 3.tags.OVERDUE""" code, out, err = self.t("_get 3.tags.OVERDUE") self.assertEqual("OVERDUE\n", out) def test_dom_due_year(self): - """ DOM 3.due.year """ + """DOM 3.due.year""" code, out, err = self.t("_get 3.due.year") self.assertEqual("2011\n", out) def test_dom_due_month(self): - """ DOM 3.due.month """ + """DOM 3.due.month""" code, out, err = self.t("_get 3.due.month") self.assertEqual("9\n", out) def test_dom_due_day(self): - """ DOM 3.due.day """ + """DOM 3.due.day""" code, out, err = self.t("_get 3.due.day") self.assertEqual("1\n", out) def test_dom_due_week(self): - """ DOM 3.due.week """ + """DOM 3.due.week""" code, out, err = self.t("_get 3.due.week") self.assertEqual("35\n", out) def test_dom_due_weekday(self): - """ DOM 3.due.weekday """ + """DOM 3.due.weekday""" code, out, err = self.t("_get 3.due.weekday") self.assertEqual("4\n", out) def test_dom_due_hour(self): - """ DOM 3.due.hour """ + """DOM 3.due.hour""" code, out, err = self.t("_get 3.due.hour") self.assertEqual("0\n", out) def test_dom_due_minute(self): - """ DOM 3.due.minute """ + """DOM 3.due.minute""" code, out, err = self.t("_get 3.due.minute") self.assertEqual("0\n", out) def test_dom_due_second(self): - """ DOM 3.due.second """ + """DOM 3.due.second""" code, out, err = self.t("_get 3.due.second") self.assertEqual("0\n", out) def test_dom_annotation_count_1(self): - """ DOM 1.annotation.count """ + """DOM 1.annotation.count""" code, out, err = self.t("_get 1.annotations.count") self.assertEqual("0\n", out) def test_dom_annotation_count_3(self): - """ DOM 3.annotation.count """ + """DOM 3.annotation.count""" code, out, err = self.t("_get 3.annotations.count") self.assertEqual("1\n", out) def test_dom_annotation_entry(self): - """ DOM 3.annotations.1.entry """ + """DOM 3.annotations.1.entry""" code, out, err = self.t("_get 3.annotations.1.entry") self.assertRegex(out, r"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}") def test_dom_annotation_entry_second(self): - """ DOM 3.annotations.1.entry """ + """DOM 3.annotations.1.entry""" code, out, err = self.t("_get 3.annotations.1.entry.second") self.assertRegex(out, r"\d{1,2}") def test_dom_annotation_description(self): - """ DOM 3.annotations.1.description """ + """DOM 3.annotations.1.description""" code, out, err = self.t("_get 3.annotations.1.description") self.assertIn("note\n", out) def test_dom_system_version(self): - """ DOM system.version """ + """DOM system.version""" code, out, err = self.t("_get system.version") self.assertEqual(code, 0) self.assertRegex(out, r"\d\.\d+\.\d+") def test_dom_system_os(self): - """ DOM system.os """ + """DOM system.os""" code, out, err = self.t("_get system.os") self.assertEqual(code, 0) self.assertEqual(len(out) > 4, True) self.assertNotIn("", out) def test_dom_tw_program(self): - """ DOM tw.program """ + """DOM tw.program""" code, out, err = self.t("_get tw.program") self.assertEqual(code, 0) self.assertIn("task", out) def test_dom_tw_args(self): - """ DOM tw.args """ + """DOM tw.args""" code, out, err = self.t("_get tw.args") self.assertEqual(code, 0) self.assertIn("task _get tw.args", out) def test_dom_tw_width(self): - """ DOM tw.width """ + """DOM tw.width""" code, out, err = self.t("_get tw.width") self.assertEqual(code, 0) self.assertRegex(out, r"\d+") def test_dom_tw_height(self): - """ DOM tw.height """ + """DOM tw.height""" code, out, err = self.t("_get tw.height") self.assertEqual(code, 0) self.assertRegex(out, r"\d+") def test_dom_tw_version(self): - """ DOM tw.version """ + """DOM tw.version""" code, out, err = self.t("_get tw.version") self.assertEqual(code, 0) self.assertRegex(out, r"\d\.\d+\.\d+") def test_dom_context_program(self): - """ DOM context.program """ + """DOM context.program""" code, out, err = self.t("_get context.program") self.assertEqual(code, 0) self.assertIn("task", out) def test_dom_context_args(self): - """ DOM context.args """ + """DOM context.args""" code, out, err = self.t("_get context.args") self.assertEqual(code, 0) self.assertIn("task _get context.args", out) def test_dom_context_width(self): - """ DOM context.width """ + """DOM context.width""" code, out, err = self.t("_get context.width") self.assertEqual(code, 0) self.assertRegex(out, r"\d+") def test_dom_context_height(self): - """ DOM context.height """ + """DOM context.height""" code, out, err = self.t("_get context.height") self.assertEqual(code, 0) self.assertRegex(out, r"\d+") def test_dom_rc_name(self): - """ DOM rc.dateformat """ + """DOM rc.dateformat""" code, out, err = self.t("_get rc.dateformat") self.assertEqual(code, 0) self.assertIn("YMD", out) def test_dom_rc_missing(self): - """ DOM rc.missing """ + """DOM rc.missing""" code, out, err = self.t("_get rc.missing") self.assertEqual("\n", out) @@ -274,10 +277,11 @@ class TestDOM(TestCase): self.assertIn("2015-09-04T00:00:00", out) def test_dom_uda_date_year(self): - """ DOM 3.due.year """ + """DOM 3.due.year""" code, out, err = self.t("_get 4.ticketdate.year") self.assertEqual("2015\n", out) + class TestDOMSync(TestCase): """ This class verifies that the 'tw.syncneeded' DOM reference properly @@ -288,14 +292,14 @@ class TestDOMSync(TestCase): self.t = Task() def test_dom_tw_syncneeded_false(self): - """ DOM tw.syncneeded --> false """ + """DOM tw.syncneeded --> false""" code, out, err = self.t("_get tw.syncneeded") self.assertEqual(code, 0) self.assertIn("0", out) self.assertNotIn("1k", out) def test_dom_tw_syncneeded_true(self): - """ DOM tw.syncneeded --> true """ + """DOM tw.syncneeded --> true""" self.t("add foo") code, out, err = self.t("_get tw.syncneeded") self.assertEqual(code, 0) @@ -339,83 +343,83 @@ class TestDOMDirectReferencesOnAddition(TestCase): cls.t("1 annotate Second annotation") def test_dom_reference_due(self): - """ DOM reference on due in add command """ + """DOM reference on due in add command""" self.t("add test_due due:1.due") latest = self.t.latest - self.assertEqual("test_due", latest['description']) - self.assertEqual("20150901T080000Z", latest['due']) + self.assertEqual("test_due", latest["description"]) + self.assertEqual("20150901T080000Z", latest["due"]) def test_dom_reference_project(self): - """ DOM reference on project in add command """ + """DOM reference on project in add command""" self.t("add test_project project:1.project") latest = self.t.latest - self.assertEqual("test_project", latest['description']) - self.assertEqual("baseproject", latest['project']) + self.assertEqual("test_project", latest["description"]) + self.assertEqual("baseproject", latest["project"]) def test_dom_reference_tags_all(self): - """ DOM reference on tags in add command """ + """DOM reference on tags in add command""" self.t("add test_tags_all tags:1.tags") latest = self.t.latest - self.assertEqual("test_tags_all", latest['description']) - self.assertEqual(["tag1","tag2"], latest['tags']) + self.assertEqual("test_tags_all", latest["description"]) + self.assertEqual(["tag1", "tag2"], latest["tags"]) def test_dom_reference_tags_single(self): - """ DOM reference on specific tag in add command """ + """DOM reference on specific tag in add command""" self.t("add test_tags_single tags:1.tags.tag1") latest = self.t.latest - self.assertEqual("test_tags_single", latest['description']) - self.assertEqual(["tag1"], latest['tags']) + self.assertEqual("test_tags_single", latest["description"]) + self.assertEqual(["tag1"], latest["tags"]) def test_dom_reference_annotation(self): - """ DOM reference on annotation description in add command """ + """DOM reference on annotation description in add command""" self.t("add description:1.annotations.2.description") latest = self.t.latest - self.assertEqual("Second annotation", latest['description']) + self.assertEqual("Second annotation", latest["description"]) def test_dom_reference_numeric_uda(self): - """ DOM reference on numeric UDA in add command """ + """DOM reference on numeric UDA in add command""" self.t("add test_numeric_uda ticketnum:1.ticketnum") latest = self.t.latest - self.assertEqual("test_numeric_uda", latest['description']) - self.assertEqual(42, latest['ticketnum']) + self.assertEqual("test_numeric_uda", latest["description"]) + self.assertEqual(42, latest["ticketnum"]) def test_dom_reference_date_uda(self): - """ DOM reference on date UDA in add command """ + """DOM reference on date UDA in add command""" self.t("add test_date_uda ticketdate:1.ticketdate") latest = self.t.latest - self.assertEqual("test_date_uda", latest['description']) - self.assertEqual("20150903T080000Z", latest['ticketdate']) + self.assertEqual("test_date_uda", latest["description"]) + self.assertEqual("20150903T080000Z", latest["ticketdate"]) def test_dom_reference_string_uda(self): - """ DOM reference on string UDA in add command """ + """DOM reference on string UDA in add command""" self.t("add test_string_uda ticketnote:1.ticketnote") latest = self.t.latest - self.assertEqual("test_string_uda", latest['description']) - self.assertEqual("This is awesome", latest['ticketnote']) + self.assertEqual("test_string_uda", latest["description"]) + self.assertEqual("This is awesome", latest["ticketnote"]) def test_dom_reference_string_value_uda(self): - """ DOM reference on string with limited values UDA in add command """ + """DOM reference on string with limited values UDA in add command""" self.t("add test_string_value_uda ticketflag:1.ticketflag") latest = self.t.latest - self.assertEqual("test_string_value_uda", latest['description']) - self.assertEqual("B", latest['ticketflag']) + self.assertEqual("test_string_value_uda", latest["description"]) + self.assertEqual("B", latest["ticketflag"]) def test_dom_reference_duration_uda(self): - """ DOM reference on duration UDA in add command """ + """DOM reference on duration UDA in add command""" self.t("add test_duration_uda ticketest:1.ticketest") latest = self.t.latest - self.assertEqual("test_duration_uda", latest['description']) - self.assertEqual("PT1H", latest['ticketest']) + self.assertEqual("test_duration_uda", latest["description"]) + self.assertEqual("PT1H", latest["ticketest"]) class TestDOMDirectReferencesFiltering(TestCase): @@ -455,44 +459,44 @@ class TestDOMDirectReferencesFiltering(TestCase): cls.t("add non matching task") def test_dom_filter_reference_due(self): - """ DOM reference on due in filter """ + """DOM reference on due in filter""" result = self.t.export_one("due:1.due") - self.assertEqual("matching task", result['description']) + self.assertEqual("matching task", result["description"]) def test_dom_filter_reference_project(self): - """ DOM reference on project in filter """ + """DOM reference on project in filter""" result = self.t.export_one("project:1.project") - self.assertEqual("matching task", result['description']) + self.assertEqual("matching task", result["description"]) def test_dom_filter_reference_tags_all(self): - """ DOM reference on tags in filter """ + """DOM reference on tags in filter""" result = self.t.export_one("tags:1.tags") - self.assertEqual("matching task", result['description']) + self.assertEqual("matching task", result["description"]) def test_dom_filter_reference_numeric_uda(self): - """ DOM reference on numeric UDA in filter """ + """DOM reference on numeric UDA in filter""" result = self.t.export_one("ticketnum:1.ticketnum") - self.assertEqual("matching task", result['description']) + self.assertEqual("matching task", result["description"]) def test_dom_filter_reference_date_uda(self): - """ DOM reference on date UDA in filter """ + """DOM reference on date UDA in filter""" result = self.t.export_one("ticketdate:1.ticketdate") - self.assertEqual("matching task", result['description']) + self.assertEqual("matching task", result["description"]) def test_dom_filter_reference_string_uda(self): - """ DOM reference on string UDA in filter """ + """DOM reference on string UDA in filter""" result = self.t.export_one("ticketnote:1.ticketnote") - self.assertEqual("matching task", result['description']) + self.assertEqual("matching task", result["description"]) def test_dom_filter_reference_string_value_uda(self): - """ DOM reference on string with limited values UDA in filter """ + """DOM reference on string with limited values UDA in filter""" result = self.t.export_one("ticketflag:1.ticketflag") - self.assertEqual("matching task", result['description']) + self.assertEqual("matching task", result["description"]) def test_dom_filter_reference_duration_uda(self): - """ DOM reference on duration UDA in filter """ + """DOM reference on duration UDA in filter""" result = self.t.export_one("ticketest:1.ticketest") - self.assertEqual("matching task", result['description']) + self.assertEqual("matching task", result["description"]) class TestBug1300(TestCase): @@ -501,18 +505,17 @@ class TestBug1300(TestCase): cls.t = Task() def test_dom_exit_status_good(self): - """1300: If the DOM recognizes a reference, it should return '0' - """ + """1300: If the DOM recognizes a reference, it should return '0'""" self.t("_get context.program") def test_dom_exit_status_bad(self): - """1300: If the DOM does not recognize a reference, it should return '1' - """ + """1300: If the DOM does not recognize a reference, it should return '1'""" self.t.runError("_get XYZ") if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/due.test.py b/test/due.test.py index 80943dfc4..c78f4688b 100755 --- a/test/due.test.py +++ b/test/due.test.py @@ -29,6 +29,7 @@ import sys import os import unittest from datetime import datetime, timedelta + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -138,6 +139,7 @@ class TestBug2519(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/duplicate.test.py b/test/duplicate.test.py index 86c66695f..d1bef3049 100755 --- a/test/duplicate.test.py +++ b/test/duplicate.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -64,7 +65,10 @@ class TestDuplication(TestCase): def test_duplication_showing_uuid(self): """Verify duplicate can show uuid""" code, out, err = self.t("1 duplicate rc.verbose:new-uuid") - self.assertRegex(out, "[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}") + self.assertRegex( + out, + "[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}", + ) class TestDuplication2(TestCase): @@ -75,7 +79,7 @@ class TestDuplication2(TestCase): def test_duplication_recurrence(self): """Verify that recurring tasks are properly duplicated""" self.t("add R due:tomorrow recur:weekly") - self.t("list") # To force handleRecurrence(). + self.t("list") # To force handleRecurrence(). code, out, err = self.t("1 duplicate") self.assertIn("The duplicated task is too", out) @@ -83,7 +87,7 @@ class TestDuplication2(TestCase): code, out, err = self.t("2 duplicate") self.assertIn("The duplicated task is not", out) - self.t("list") # To force handleRecurrence(). + self.t("list") # To force handleRecurrence(). code, out, err = self.t("1 export") self.assertIn('"status":"recurring"', out) @@ -105,6 +109,7 @@ class TestDuplication2(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/edit.test.py b/test/edit.test.py index 92378378d..57891f732 100755 --- a/test/edit.test.py +++ b/test/edit.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -86,7 +87,9 @@ class TestTaskEdit(TestCase): self.t.config("uda.uorphan.type", "string") self.t.config("uda.uorphan.label", "uorphan") - self.t("add foo project:P +tag priority:H start:now due:eom wait:eom scheduled:eom recur:P1M until:eoy udate:now uduration:1day ustring:Hi unumeric:42 uorphan:Annie") + self.t( + "add foo project:P +tag priority:H start:now due:eom wait:eom scheduled:eom recur:P1M until:eoy udate:now uduration:1day ustring:Hi unumeric:42 uorphan:Annie" + ) self.t("1 annotate bar", input="n\n") # Make the orphan. @@ -99,6 +102,7 @@ class TestTaskEdit(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/encoding.test.py b/test/encoding.test.py index b00632a07..13b4973c6 100755 --- a/test/encoding.test.py +++ b/test/encoding.test.py @@ -29,6 +29,7 @@ import sys import os import re import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -77,6 +78,7 @@ class TestUtf8(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/enpassant.test.py b/test/enpassant.test.py index 3f28d76a8..b68c0639a 100755 --- a/test/enpassant.test.py +++ b/test/enpassant.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -54,19 +55,23 @@ class TestEnpassantMultiple(BaseTestEnpassant): code, out, err = self.t((id, "info")) self.assertRegex( - out, "Status +Completed", + out, + "Status +Completed", msg="enpassant {0} status change".format(id), ) self.assertRegex( - out, "Priority +H", + out, + "Priority +H", msg="enpassant {0} priority change".format(id), ) self.assertRegex( - out, "Tags +tag", + out, + "Tags +tag", msg="enpassant {0} tag change".format(id), ) self.assertRegex( - out, "Description +{0}".format(desc), + out, + "Description +{0}".format(desc), msg="enpassant {0} description change".format(id), ) @@ -94,28 +99,33 @@ class TestEnpassant(BaseTestEnpassant): def perform_action(self, action): self.t(("1", action, "oneanno")) code, out, err = self.t("1 info") - self.assertRegex(out, "Description +one\n[0-9: -]+ oneanno", - msg="{0} enpassant annotation".format(action)) + self.assertRegex( + out, + "Description +one\n[0-9: -]+ oneanno", + msg="{0} enpassant annotation".format(action), + ) self.t(("2", action, "/two/TWO/")) code, out, err = self.t("2 info") - self.assertRegex(out, "Description +TWO", - msg="{0} enpassant modify".format(action)) + self.assertRegex( + out, "Description +TWO", msg="{0} enpassant modify".format(action) + ) self.t(("3", action, "+threetag")) code, out, err = self.t("3 info") - self.assertRegex(out, "Tags +threetag", - msg="{0} enpassant tag".format(action)) + self.assertRegex(out, "Tags +threetag", msg="{0} enpassant tag".format(action)) self.t(("4", action, "pri:H")) code, out, err = self.t("4 info") - self.assertRegex(out, "Priority +H", - msg="{0} enpassant priority".format(action)) + self.assertRegex( + out, "Priority +H", msg="{0} enpassant priority".format(action) + ) self.t(("5", action, "pro:PROJ")) code, out, err = self.t("5 info") - self.assertRegex(out, "Project +PROJ", - msg="{0} enpassant project".format(action)) + self.assertRegex( + out, "Project +PROJ", msg="{0} enpassant project".format(action) + ) def test_done(self): """Test 'done' with en-passant changes""" @@ -138,6 +148,7 @@ class TestEnpassant(BaseTestEnpassant): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/eval.test.cpp b/test/eval.test.cpp index f5969bdb5..3875da5ac 100644 --- a/test/eval.test.cpp +++ b/test/eval.test.cpp @@ -27,16 +27,15 @@ #include // cmake.h include header must come first -#include #include #include +#include //////////////////////////////////////////////////////////////////////////////// // A few hard-coded symbols. -bool get (const std::string& name, Variant& value) -{ +bool get(const std::string& name, Variant& value) { if (name == "x") - value = Variant (true); + value = Variant(true); else return false; @@ -44,126 +43,125 @@ bool get (const std::string& name, Variant& value) } //////////////////////////////////////////////////////////////////////////////// -int main (int, char**) -{ - UnitTest t (52); +int main(int, char**) { + UnitTest t(52); Context context; Context::setContext(&context); // Test the source independently. Variant v; - t.notok (get ("-", v), "true <-- get(-)"); + t.notok(get("-", v), "true <-- get(-)"); - t.ok (get ("x", v), "true <-- get(x)"); - t.is (v.type (), Variant::type_boolean, "get(x) --> boolean"); - t.is (v.get_bool (), true, "get(x) --> true"); + t.ok(get("x", v), "true <-- get(x)"); + t.is(v.type(), Variant::type_boolean, "get(x) --> boolean"); + t.is(v.get_bool(), true, "get(x) --> true"); Eval e; - e.addSource (get); + e.addSource(get); Variant result; - e.evaluatePostfixExpression ("x", result); - t.is (result.type (), Variant::type_boolean, "postfix 'x' --> boolean"); - t.is (result.get_bool (), true, "postfix 'x' --> true"); + e.evaluatePostfixExpression("x", result); + t.is(result.type(), Variant::type_boolean, "postfix 'x' --> boolean"); + t.is(result.get_bool(), true, "postfix 'x' --> true"); - e.evaluatePostfixExpression ("pi", result); - t.is (result.type (), Variant::type_real, "postfix 'pi' --> real"); - t.is (result.get_real (), 3.141592, 0.00001, "postfix 'pi' --> 3.14159265"); + e.evaluatePostfixExpression("pi", result); + t.is(result.type(), Variant::type_real, "postfix 'pi' --> real"); + t.is(result.get_real(), 3.141592, 0.00001, "postfix 'pi' --> 3.14159265"); - e.evaluatePostfixExpression ("foo", result); - t.is (result.type (), Variant::type_string, "postfix 'foo' --> string"); - t.is (result.get_string (), "foo", "postfix 'foo' --> 'foo'"); + e.evaluatePostfixExpression("foo", result); + t.is(result.type(), Variant::type_string, "postfix 'foo' --> string"); + t.is(result.get_string(), "foo", "postfix 'foo' --> 'foo'"); // Simple infix arithmetic. - e.evaluateInfixExpression ("1+2", result); - t.is (result.type (), Variant::type_integer, "infix '1 + 2' --> integer"); - t.is (result.get_integer (), 3, "infix '1 + 2' --> 3"); + e.evaluateInfixExpression("1+2", result); + t.is(result.type(), Variant::type_integer, "infix '1 + 2' --> integer"); + t.is(result.get_integer(), 3, "infix '1 + 2' --> 3"); // Simple postfix arithmetic. - e.evaluatePostfixExpression ("1 2 +", result); - t.is (result.type (), Variant::type_integer, "postfix '1 2 +' --> integer"); - t.is (result.get_integer (), 3, "postfix '1 2 +' --> 3"); + e.evaluatePostfixExpression("1 2 +", result); + t.is(result.type(), Variant::type_integer, "postfix '1 2 +' --> integer"); + t.is(result.get_integer(), 3, "postfix '1 2 +' --> 3"); - e.evaluatePostfixExpression ("1 2 -", result); - t.is (result.type (), Variant::type_integer, "postfix '1 2 -' --> integer"); - t.is (result.get_integer (), -1, "postfix '1 2 -' --> -1"); + e.evaluatePostfixExpression("1 2 -", result); + t.is(result.type(), Variant::type_integer, "postfix '1 2 -' --> integer"); + t.is(result.get_integer(), -1, "postfix '1 2 -' --> -1"); - e.evaluatePostfixExpression ("2 3 *", result); - t.is (result.type (), Variant::type_integer, "postfix '2 3 *' --> integer"); - t.is (result.get_integer (), 6, "postfix '2 3 *' --> 6"); + e.evaluatePostfixExpression("2 3 *", result); + t.is(result.type(), Variant::type_integer, "postfix '2 3 *' --> integer"); + t.is(result.get_integer(), 6, "postfix '2 3 *' --> 6"); - e.evaluatePostfixExpression ("5 2 /", result); - t.is (result.type (), Variant::type_integer, "postfix '5 2 /' --> integer"); - t.is (result.get_integer (), 2, "postfix '5 2 /' --> 2"); + e.evaluatePostfixExpression("5 2 /", result); + t.is(result.type(), Variant::type_integer, "postfix '5 2 /' --> integer"); + t.is(result.get_integer(), 2, "postfix '5 2 /' --> 2"); - e.evaluatePostfixExpression ("5 2 /", result); - t.is (result.type (), Variant::type_integer, "postfix '5 2 *' --> integer"); - t.is (result.get_integer (), 2, "postfix '5 2 *' --> 2"); + e.evaluatePostfixExpression("5 2 /", result); + t.is(result.type(), Variant::type_integer, "postfix '5 2 *' --> integer"); + t.is(result.get_integer(), 2, "postfix '5 2 *' --> 2"); // Simple postfix unary operator. - e.evaluatePostfixExpression ("0 !", result); - t.is (result.type (), Variant::type_boolean, "postfix '0 !' --> boolean"); - t.is (result.get_bool (), true, "postfix '0 !' --> true"); + e.evaluatePostfixExpression("0 !", result); + t.is(result.type(), Variant::type_boolean, "postfix '0 !' --> boolean"); + t.is(result.get_bool(), true, "postfix '0 !' --> true"); - e.evaluatePostfixExpression ("1 !", result); - t.is (result.type (), Variant::type_boolean, "postfix '1 !' --> boolean"); - t.is (result.get_bool (), false, "postfix '1 !' --> false"); + e.evaluatePostfixExpression("1 !", result); + t.is(result.type(), Variant::type_boolean, "postfix '1 !' --> boolean"); + t.is(result.get_bool(), false, "postfix '1 !' --> false"); // Type promotion simple postfix arithmetic. - e.evaluatePostfixExpression ("1 2.3 +", result); - t.is (result.type (), Variant::type_real, "postfix '1 2.3 +' --> real"); - t.is (result.get_real (), 3.3, "postfix '1 2.3 +' --> 3.3"); + e.evaluatePostfixExpression("1 2.3 +", result); + t.is(result.type(), Variant::type_real, "postfix '1 2.3 +' --> real"); + t.is(result.get_real(), 3.3, "postfix '1 2.3 +' --> 3.3"); - e.evaluatePostfixExpression ("5 2.0 /", result); - t.is (result.type (), Variant::type_real, "postfix '5 2.0 /' --> integer"); - t.is (result.get_real (), 2.5, "postfix '5 2.0 /' --> 2.5"); + e.evaluatePostfixExpression("5 2.0 /", result); + t.is(result.type(), Variant::type_real, "postfix '5 2.0 /' --> integer"); + t.is(result.get_real(), 2.5, "postfix '5 2.0 /' --> 2.5"); // Simple logic. - e.evaluatePostfixExpression ("0 0 ||", result); - t.is (result.type (), Variant::type_boolean, "postfix '0 0 ||' --> boolean"); - t.is (result.get_bool (), false, "postfix '0 0 ||' --> false"); + e.evaluatePostfixExpression("0 0 ||", result); + t.is(result.type(), Variant::type_boolean, "postfix '0 0 ||' --> boolean"); + t.is(result.get_bool(), false, "postfix '0 0 ||' --> false"); - e.evaluatePostfixExpression ("0 1 ||", result); - t.is (result.type (), Variant::type_boolean, "postfix '0 1 ||' --> boolean"); - t.is (result.get_bool (), true, "postfix '0 1 ||' --> true"); + e.evaluatePostfixExpression("0 1 ||", result); + t.is(result.type(), Variant::type_boolean, "postfix '0 1 ||' --> boolean"); + t.is(result.get_bool(), true, "postfix '0 1 ||' --> true"); - e.evaluatePostfixExpression ("1 0 ||", result); - t.is (result.type (), Variant::type_boolean, "postfix '1 0 ||' --> boolean"); - t.is (result.get_bool (), true, "postfix '1 0 ||' --> true"); + e.evaluatePostfixExpression("1 0 ||", result); + t.is(result.type(), Variant::type_boolean, "postfix '1 0 ||' --> boolean"); + t.is(result.get_bool(), true, "postfix '1 0 ||' --> true"); - e.evaluatePostfixExpression ("1 1 ||", result); - t.is (result.type (), Variant::type_boolean, "postfix '1 1 ||' --> boolean"); - t.is (result.get_bool (), true, "postfix '1 1 ||' --> true"); + e.evaluatePostfixExpression("1 1 ||", result); + t.is(result.type(), Variant::type_boolean, "postfix '1 1 ||' --> boolean"); + t.is(result.get_bool(), true, "postfix '1 1 ||' --> true"); - e.evaluateInfixExpression ("2*3+1", result); - t.is (result.type (), Variant::type_integer, "infix '2*3+1' --> integer"); - t.is (result.get_integer (), 7, "infix '2*3+1' --> 7"); + e.evaluateInfixExpression("2*3+1", result); + t.is(result.type(), Variant::type_integer, "infix '2*3+1' --> integer"); + t.is(result.get_integer(), 7, "infix '2*3+1' --> 7"); // TW-1254 - Unary minus support. - e.evaluateInfixExpression ("2- -3", result); - t.is (result.type (), Variant::type_integer, "infix '2- -3' --> integer"); - t.is (result.get_integer (), 5, "infix '2- -3' --> 5"); + e.evaluateInfixExpression("2- -3", result); + t.is(result.type(), Variant::type_integer, "infix '2- -3' --> integer"); + t.is(result.get_integer(), 5, "infix '2- -3' --> 5"); - //e.debug (); - e.evaluateInfixExpression ("!false", result); - t.is (result.type (), Variant::type_boolean, "infix '!false' --> boolean"); - t.is (result.get_bool (), true, "infix '!false' --> true"); + // e.debug (); + e.evaluateInfixExpression("!false", result); + t.is(result.type(), Variant::type_boolean, "infix '!false' --> boolean"); + t.is(result.get_bool(), true, "infix '!false' --> true"); - e.evaluateInfixExpression ("!true", result); - t.is (result.type (), Variant::type_boolean, "infix '!true' --> boolean"); - t.is (result.get_bool (), false, "infix '!true' --> false"); + e.evaluateInfixExpression("!true", result); + t.is(result.type(), Variant::type_boolean, "infix '!true' --> boolean"); + t.is(result.get_bool(), false, "infix '!true' --> false"); // _neg_ - e.evaluateInfixExpression ("- 1", result); - t.is (result.type (), Variant::type_integer, "infix '- 1' --> integer"); - t.is (result.get_integer (), -1, "infix '- 1' --> -1"); + e.evaluateInfixExpression("- 1", result); + t.is(result.type(), Variant::type_integer, "infix '- 1' --> integer"); + t.is(result.get_integer(), -1, "infix '- 1' --> -1"); - e.evaluateInfixExpression ("- 1.2", result); - t.is (result.type (), Variant::type_real, "infix '- 1.2' --> real"); - t.is (result.get_real (), -1.2, "infix '- 1.2' --> -1.2"); + e.evaluateInfixExpression("- 1.2", result); + t.is(result.type(), Variant::type_real, "infix '- 1.2' --> real"); + t.is(result.get_real(), -1.2, "infix '- 1.2' --> -1.2"); - e.evaluateInfixExpression ("- 2days", result); - t.is (result.type (), Variant::type_duration, "infix '- 2days' --> duration"); - t.is (result.get_duration (), -86400*2, "infix '- 2days' --> -86400 * 2"); + e.evaluateInfixExpression("- 2days", result); + t.is(result.type(), Variant::type_duration, "infix '- 2days' --> duration"); + t.is(result.get_duration(), -86400 * 2, "infix '- 2days' --> -86400 * 2"); return 0; } diff --git a/test/exec.test.py b/test/exec.test.py index 394e1b025..3cad4e32c 100755 --- a/test/exec.test.py +++ b/test/exec.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + sys.path.append(os.path.dirname(os.path.abspath(__file__))) from basetest import Task, TestCase @@ -63,8 +64,10 @@ class TestBug1414(TestCase): code, out, err = self.t() self.assertIn("hello", out) + if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/export.test.py b/test/export.test.py index c3637fbb2..777bcf227 100755 --- a/test/export.test.py +++ b/test/export.test.py @@ -45,7 +45,7 @@ DATETIME_FORMAT = "%Y%m%dT%H%M%SZ" class TestExportCommand(TestCase): def setUp(self): self.t = Task() - self.t('add test') + self.t("add test") def export(self, id): code, out, err = self.t(("{0}".format(id), "rc.json.array=off", "export")) @@ -91,62 +91,62 @@ class TestExportCommand(TestCase): self.assertEqual(value, expected_value) def test_export_status(self): - self.assertString(self.export(1)['status'], "pending") + self.assertString(self.export(1)["status"], "pending") def test_export_uuid(self): - self.assertString(self.export(1)['uuid'], UUID_REGEXP, regexp=True) + self.assertString(self.export(1)["uuid"], UUID_REGEXP, regexp=True) def test_export_entry(self): - self.assertTimestamp(self.export(1)['entry']) + self.assertTimestamp(self.export(1)["entry"]) def test_export_description(self): - self.assertString(self.export(1)['description'], "test") + self.assertString(self.export(1)["description"], "test") def test_export_start(self): - self.t('1 start') - self.assertTimestamp(self.export(1)['start']) + self.t("1 start") + self.assertTimestamp(self.export(1)["start"]) def test_export_end(self): - self.t('1 start') + self.t("1 start") self.t.faketime("+5s") # After a task is "done" or "deleted", it does not have an ID by which # to filter it anymore. Add a tag to work around this. - self.t('1 done +workaround') - self.assertTimestamp(self.export('+workaround')['end']) + self.t("1 done +workaround") + self.assertTimestamp(self.export("+workaround")["end"]) def test_export_due(self): - self.t('1 modify due:today') - self.assertTimestamp(self.export(1)['due']) + self.t("1 modify due:today") + self.assertTimestamp(self.export(1)["due"]) def test_export_wait(self): - self.t('1 modify wait:tomorrow') - self.assertTimestamp(self.export(1)['wait']) + self.t("1 modify wait:tomorrow") + self.assertTimestamp(self.export(1)["wait"]) def test_export_modified(self): - self.assertTimestamp(self.export(1)['modified']) + self.assertTimestamp(self.export(1)["modified"]) def test_export_scheduled(self): - self.t('1 modify schedule:tomorrow') - self.assertTimestamp(self.export(1)['scheduled']) + self.t("1 modify schedule:tomorrow") + self.assertTimestamp(self.export(1)["scheduled"]) def test_export_recur(self): - self.t('1 modify recur:daily due:today') - self.assertString(self.export(1)['recur'], "daily") + self.t("1 modify recur:daily due:today") + self.assertString(self.export(1)["recur"], "daily") def test_export_project(self): - self.t('1 modify project:Home') - self.assertString(self.export(1)['project'], "Home") + self.t("1 modify project:Home") + self.assertString(self.export(1)["project"], "Home") def test_export_priority(self): - self.t('1 modify priority:H') - self.assertString(self.export(1)['priority'], "H") + self.t("1 modify priority:H") + self.assertString(self.export(1)["priority"], "H") def test_export_depends(self): - self.t(('add', 'everything depends on me task')) - self.t(('add', 'wrong, everything depends on me task')) - self.t('1 modify depends:2,3') + self.t(("add", "everything depends on me task")) + self.t(("add", "wrong, everything depends on me task")) + self.t("1 modify depends:2,3") - deps = self.export(1)['depends'] + deps = self.export(1)["depends"] self.assertType(deps, list) self.assertEqual(len(deps), 2) @@ -154,30 +154,30 @@ class TestExportCommand(TestCase): self.assertString(uuid, UUID_REGEXP, regexp=True) def test_export_urgency(self): - self.t('add urgent task +urgent') + self.t("add urgent task +urgent") # Urgency can be either integer or float - self.assertNumeric(self.export(1)['urgency']) + self.assertNumeric(self.export(1)["urgency"]) def test_export_numeric_uda(self): - self.t.config('uda.estimate.type', 'numeric') - self.t('add estimate:42 test numeric uda') - self.assertNumeric(self.export('2')['estimate'], 42) + self.t.config("uda.estimate.type", "numeric") + self.t("add estimate:42 test numeric uda") + self.assertNumeric(self.export("2")["estimate"], 42) def test_export_string_uda(self): - self.t.config('uda.estimate.type', 'string') - self.t('add estimate:big test string uda') - self.assertString(self.export('2')['estimate'], 'big') + self.t.config("uda.estimate.type", "string") + self.t("add estimate:big test string uda") + self.assertString(self.export("2")["estimate"], "big") def test_export_datetime_uda(self): - self.t.config('uda.estimate.type', 'date') - self.t('add estimate:eom test date uda') - self.assertTimestamp(self.export('2')['estimate']) + self.t.config("uda.estimate.type", "date") + self.t("add estimate:eom test date uda") + self.assertTimestamp(self.export("2")["estimate"]) def test_export_duration_uda(self): - self.t.config('uda.estimate.type', 'duration') - self.t('add estimate:month test duration uda') - self.assertString(self.export('2')['estimate'], 'P30D') + self.t.config("uda.estimate.type", "duration") + self.t("add estimate:month test duration uda") + self.assertString(self.export("2")["estimate"], "P30D") class TestExportCommandLimit(TestCase): @@ -186,8 +186,8 @@ class TestExportCommandLimit(TestCase): def test_export_obeys_limit(self): """Verify that 'task export limit:1' is obeyed""" - self.t('add one') - self.t('add two') + self.t("add one") + self.t("add two") code, out, err = self.t("/o/ limit:1 export") self.assertIn("one", out) @@ -196,6 +196,7 @@ class TestExportCommandLimit(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/feature.559.test.py b/test/feature.559.test.py index 42b1bec25..c0c5afa8f 100755 --- a/test/feature.559.test.py +++ b/test/feature.559.test.py @@ -29,6 +29,7 @@ import sys import os import re import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -67,11 +68,14 @@ class TestFeature559(TestCase): code, out, err = self.t.runError("rc.data.location=locationdoesnotexist list") self.assertNotIn("footask", out) self.assertNotIn("Error", out) - self.assertRegex(err, re.compile("Could not.+unable to open database file", re.DOTALL)) + self.assertRegex( + err, re.compile("Could not.+unable to open database file", re.DOTALL) + ) if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/feature.default.project.test.py b/test/feature.default.project.test.py index dc2cce7fc..558b081fe 100755 --- a/test/feature.default.project.test.py +++ b/test/feature.default.project.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -35,8 +36,8 @@ from basetest import Task, TestCase class TestDefaultProject(TestCase): - """Bug 1023: rc.default.project gets applied during modify, and should not - """ + """Bug 1023: rc.default.project gets applied during modify, and should not""" + def setUp(self): self.t = Task() @@ -45,8 +46,7 @@ class TestDefaultProject(TestCase): self.t.config("default.project", self.default_project) def test_with_project(self): - """default.project not applied when specified nor on attribute removal - """ + """default.project not applied when specified nor on attribute removal""" self.set_default_project() self.t("add foobar project:garden") @@ -152,7 +152,7 @@ class TestDefaultProject(TestCase): self.set_default_project() DESC = "foobar" - self.t(('add', 'recur:daily', 'due:today', DESC)) + self.t(("add", "recur:daily", "due:today", DESC)) self.t() # Ensure creation of recurring children code, out, err = self.t("1 info") @@ -172,8 +172,10 @@ class TestDefaultProject(TestCase): try: id = int(id) except ValueError: - raise ValueError("Unexpected output when running 'task count', " - "expected int, got '{0}'".format(id)) + raise ValueError( + "Unexpected output when running 'task count', " + "expected int, got '{0}'".format(id) + ) else: # parent task is not considered when counting id = str(id + 1) @@ -188,7 +190,7 @@ class TestDefaultProject(TestCase): """no project is applied on recurring tasks""" # NOTE - reported on TW-1279 DESC = "foobar" - self.t(('add', 'recur:daily', 'due:today', DESC)) + self.t(("add", "recur:daily", "due:today", DESC)) code, out, err = self.t() self.assertIn(DESC, out) @@ -204,13 +206,12 @@ class TestDefaultProject(TestCase): self.assertNotIn("Project", out) def test_recurring_with_project_and_default_project(self): - """default.project is not applied to children if parent has a project - """ + """default.project is not applied to children if parent has a project""" # NOTE - reported on TW-1279 self.set_default_project() DESC = "foobar" - self.t(('add', 'recur:daily', 'due:today', 'project:HELLO', DESC)) + self.t(("add", "recur:daily", "due:today", "project:HELLO", DESC)) code, out, err = self.t() self.assertIn(DESC, out) @@ -227,6 +228,7 @@ class TestDefaultProject(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/feature.print.empty.columns.test.py b/test/feature.print.empty.columns.test.py index 66281e017..e68654a08 100755 --- a/test/feature.print.empty.columns.test.py +++ b/test/feature.print.empty.columns.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -39,7 +40,6 @@ class TestPrintEmptyColumns(TestCase): """Executed before each test in the class""" self.t = Task() - def test_empty_columns_feature(self): """Verify rc.print.empty.columns:yes shows more nothing than rc.print.empty.columns:no""" self.t("add one") @@ -64,6 +64,7 @@ class TestPrintEmptyColumns(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/feature.recurrence.test.py b/test/feature.recurrence.test.py index 0f50da486..ea48bc724 100755 --- a/test/feature.recurrence.test.py +++ b/test/feature.recurrence.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + sys.path.append(os.path.dirname(os.path.abspath(__file__))) from basetest import Task, TestCase @@ -67,6 +68,7 @@ class TestRecurrenceProblems(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/feedback.test.py b/test/feedback.test.py index de652da48..6ab97eefd 100755 --- a/test/feedback.test.py +++ b/test/feedback.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -69,6 +70,7 @@ class TestFeature1013(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/filter.test.py b/test/filter.test.py index 6c39b3906..47e32eccd 100755 --- a/test/filter.test.py +++ b/test/filter.test.py @@ -29,6 +29,7 @@ import sys import os import unittest import datetime + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -353,7 +354,7 @@ class TestFilterDue(TestCase): def setUp(self): self.t = Task() - self.t.config("due", "4") + self.t.config("due", "4") self.t.config("dateformat", "m/d/Y") just = datetime.datetime.now() + datetime.timedelta(days=3) @@ -441,7 +442,9 @@ class TestEmptyFilter(TestCase): self.t("add foo") self.t("add bar") - code, out, err = self.t.runError("modify rc.allow.empty.filter=yes rc.confirmation=no priority:H") + code, out, err = self.t.runError( + "modify rc.allow.empty.filter=yes rc.confirmation=no priority:H" + ) self.assertIn("Command prevented from running.", err) def test_empty_filter_error(self): @@ -451,7 +454,10 @@ class TestEmptyFilter(TestCase): self.t("add bar") code, out, err = self.t.runError("modify rc.allow.empty.filter=no priority:H") - self.assertIn("You did not specify a filter, and with the 'allow.empty.filter' value, no action is taken.", err) + self.assertIn( + "You did not specify a filter, and with the 'allow.empty.filter' value, no action is taken.", + err, + ) class TestFilterPrefix(TestCase): @@ -461,86 +467,86 @@ class TestFilterPrefix(TestCase): cls.t = Task() cls.t.config("verbose", "nothing") - cls.t('add project:foo.uno priority:H +tag "one foo"' ) - cls.t('add project:foo.dos priority:H "two"' ) - cls.t('add project:foo.tres "three"' ) - cls.t('add project:bar.uno priority:H "four"' ) - cls.t('add project:bar.dos +tag "five"' ) - cls.t('add project:bar.tres "six foo"' ) + cls.t('add project:foo.uno priority:H +tag "one foo"') + cls.t('add project:foo.dos priority:H "two"') + cls.t('add project:foo.tres "three"') + cls.t('add project:bar.uno priority:H "four"') + cls.t('add project:bar.dos +tag "five"') + cls.t('add project:bar.tres "six foo"') cls.t('add project:bazuno "seven bar foo"') cls.t('add project:bazdos "eight bar foo"') def test_list_all(self): """No filter shows all tasks.""" - code, out, err = self.t('list') - self.assertIn('one', out) - self.assertIn('two', out) - self.assertIn('three', out) - self.assertIn('four', out) - self.assertIn('five', out) - self.assertIn('six', out) - self.assertIn('seven', out) - self.assertIn('eight', out) + code, out, err = self.t("list") + self.assertIn("one", out) + self.assertIn("two", out) + self.assertIn("three", out) + self.assertIn("four", out) + self.assertIn("five", out) + self.assertIn("six", out) + self.assertIn("seven", out) + self.assertIn("eight", out) def test_list_project_foo(self): """Filter on project name.""" - code, out, err = self.t('list project:foo') - self.assertIn('one', out) - self.assertIn('two', out) - self.assertIn('three', out) - self.assertNotIn('four', out) - self.assertNotIn('five', out) - self.assertNotIn('six', out) - self.assertNotIn('seven', out) - self.assertNotIn('eight', out) + code, out, err = self.t("list project:foo") + self.assertIn("one", out) + self.assertIn("two", out) + self.assertIn("three", out) + self.assertNotIn("four", out) + self.assertNotIn("five", out) + self.assertNotIn("six", out) + self.assertNotIn("seven", out) + self.assertNotIn("eight", out) def test_list_project_not_foo(self): """Filter on not project name.""" - code, out, err = self.t('list project.not:foo') - self.assertNotIn('one', out) - self.assertNotIn('two', out) - self.assertNotIn('three', out) - self.assertIn('four', out) - self.assertIn('five', out) - self.assertIn('six', out) - self.assertIn('seven', out) - self.assertIn('eight', out) + code, out, err = self.t("list project.not:foo") + self.assertNotIn("one", out) + self.assertNotIn("two", out) + self.assertNotIn("three", out) + self.assertIn("four", out) + self.assertIn("five", out) + self.assertIn("six", out) + self.assertIn("seven", out) + self.assertIn("eight", out) def test_list_project_startswith_bar(self): """Filter on project name start.""" - code, out, err = self.t('list project.startswith:bar') - self.assertNotIn('one', out) - self.assertNotIn('two', out) - self.assertNotIn('three', out) - self.assertIn('four', out) - self.assertIn('five', out) - self.assertIn('six', out) - self.assertNotIn('seven', out) - self.assertNotIn('eight', out) + code, out, err = self.t("list project.startswith:bar") + self.assertNotIn("one", out) + self.assertNotIn("two", out) + self.assertNotIn("three", out) + self.assertIn("four", out) + self.assertIn("five", out) + self.assertIn("six", out) + self.assertNotIn("seven", out) + self.assertNotIn("eight", out) def test_list_project_ba(self): """Filter on project partial match.""" - code, out, err = self.t('list project:ba') - self.assertNotIn('one', out) - self.assertNotIn('two', out) - self.assertNotIn('three', out) - self.assertIn('four', out) - self.assertIn('five', out) - self.assertIn('six', out) - self.assertIn('seven', out) - self.assertIn('eight', out) + code, out, err = self.t("list project:ba") + self.assertNotIn("one", out) + self.assertNotIn("two", out) + self.assertNotIn("three", out) + self.assertIn("four", out) + self.assertIn("five", out) + self.assertIn("six", out) + self.assertIn("seven", out) + self.assertIn("eight", out) def test_list_description_has_foo(self): """Filter on description pattern.""" - code, out, err = self.t('list description.has:foo') - self.assertIn('one', out) - self.assertNotIn('two', out) - self.assertNotIn('three', out) - self.assertNotIn('four', out) - self.assertNotIn('five', out) - self.assertIn('six', out) - self.assertIn('seven', out) - self.assertIn('eight', out) + code, out, err = self.t("list description.has:foo") + self.assertIn("one", out) + self.assertNotIn("two", out) + self.assertNotIn("three", out) + self.assertNotIn("four", out) + self.assertNotIn("five", out) + self.assertIn("six", out) + self.assertIn("seven", out) + self.assertIn("eight", out) class TestBug480B(TestCase): @@ -675,7 +681,7 @@ class TestBug1600(TestCase): self.assertNotIn("foobar2", out) def test_filter_question_in_descriptions(self): - """filter - description contains ? """ + """filter - description contains ?""" self.t("add foobar1") self.t("add foo?bar") @@ -688,7 +694,7 @@ class TestBug1600(TestCase): self.assertNotIn("foobar1", out) def test_filter_brackets_in_descriptions(self): - """filter - description contains [] """ + """filter - description contains []""" self.t("add [foobar1]") self.t("add [foobar2]") @@ -707,9 +713,9 @@ class TestBug1656(TestCase): def test_report_filter_parenthesized(self): """default report filter parenthesized""" - self.t('add task1 +work') - self.t('add task2 +work') - self.t('1 done') + self.t("add task1 +work") + self.t("add task2 +work") + self.t("1 done") # Sanity check, next does not display completed tasks code, out, err = self.t("next") @@ -747,19 +753,19 @@ class TestHasHasnt(TestCase): def test_has_hasnt(self): """Verify the 'has' and 'hasnt' attribute modifiers""" - self.t("add foo") # 1 - self.t("add foo") # 2 + self.t("add foo") # 1 + self.t("add foo") # 2 self.t("2 annotate bar") - self.t("add foo") # 3 + self.t("add foo") # 3 self.t("3 annotate bar") self.t("3 annotate baz") - self.t("add bar") # 4 - self.t("add bar") # 5 + self.t("add bar") # 4 + self.t("add bar") # 5 self.t("5 annotate foo") - self.t("add bar") # 6 + self.t("add bar") # 6 self.t("6 annotate foo") self.t("6 annotate baz") - self.t("add one") # 7 + self.t("add one") # 7 self.t("7 annotate two") self.t("7 annotate three") @@ -787,8 +793,8 @@ class TestBefore(TestCase): def setUpClass(cls): """Executed once before any test in the class""" cls.t = Task() - cls.t('add foo entry:2008-12-22 start:2008-12-22') - cls.t('add bar entry:2009-04-17 start:2009-04-17') + cls.t("add foo entry:2008-12-22 start:2008-12-22") + cls.t("add bar entry:2009-04-17 start:2009-04-17") def test_correctly_recorded_start(self): """Verify start dates properly recorded""" @@ -840,14 +846,14 @@ class TestBy(TestCase): self.t = Task() def test_by_eoy_includes_eoy(self): - """ Verify by-end-of-year includes task due *at* end-of-year """ + """Verify by-end-of-year includes task due *at* end-of-year""" self.t("add zero due:eoy") code, out, err = self.t("due.by:eoy") self.assertIn("zero", out) def test_by_tomorrow_includes_tomorrow(self): - """ Verify that by-tomorrow also includes tomorrow itself """ + """Verify that by-tomorrow also includes tomorrow itself""" self.t.faketime("2021-07-16 21:00:00") self.t("add zero due:2021-07-17") @@ -855,7 +861,7 @@ class TestBy(TestCase): self.assertIn("zero", out) def test_by_yesterday_does_not_include_today(self): - """ Verify that by-yesterday does not include today """ + """Verify that by-yesterday does not include today""" self.t("add zero") code, out, err = self.t.runError("entry.by:yesterday") @@ -869,8 +875,8 @@ class Test1424(TestCase): def test_1824_days(self): """1424: Check that due:1824d works""" - self.t('add foo due:1824d') - code, out, err = self.t('_get 1.due.year') + self.t("add foo due:1824d") + code, out, err = self.t("_get 1.due.year") # NOTE This test has a possible race condition when run "during" EOY. # If Taskwarrior is executed at 23:59:59 on new year's eve and the # python code below runs at 00:00:00 on new year's day, the two will @@ -881,8 +887,8 @@ class Test1424(TestCase): def test_3648_days(self): """1424: Check that due:3648d works""" - self.t('add foo due:3648d') - code, out, err = self.t('_get 1.due.year') + self.t("add foo due:3648d") + code, out, err = self.t("_get 1.due.year") # NOTE This test has a possible race condition when run "during" EOY. # If Taskwarrior is executed at 23:59:59 on new year's eve and the # python code below runs at 00:00:00 on new year's day, the two will @@ -897,22 +903,22 @@ class Test1424(TestCase): class Test1452(TestCase): def setUp(self): self.t = Task() - self.t('add task') - self.task_uuid = self.t.export_one()['uuid'] + self.t("add task") + self.task_uuid = self.t.export_one()["uuid"] def test_get_task_by_uuid_with_prefix(self): """1452: Tries to filter task simply by its uuid, using uuid: prefix.""" - output = self.t.export_one('uuid:%s' % self.task_uuid) + output = self.t.export_one("uuid:%s" % self.task_uuid) # Sanity check it is the correct one - self.assertEqual(output['uuid'], self.task_uuid) + self.assertEqual(output["uuid"], self.task_uuid) def test_get_task_by_uuid_without_prefix(self): """1452: Tries to filter task simply by its uuid, without using uuid: prefix.""" output = self.t.export_one(self.task_uuid) # Sanity check it is the correct one - self.assertEqual(output['uuid'], self.task_uuid) + self.assertEqual(output["uuid"], self.task_uuid) class TestBug1456(TestCase): @@ -935,22 +941,22 @@ class TestBug1456(TestCase): class Test1468(TestCase): def setUp(self): self.t = Task() - self.t('add project:home buy milk') - self.t('add project:home mow the lawn') + self.t("add project:home buy milk") + self.t("add project:home mow the lawn") def test_single_attribute_filter(self): """1468: Single attribute filter (project:home)""" - code, out, err = self.t('list project:home') + code, out, err = self.t("list project:home") self.assertEqual(0, code, "Exit code was non-zero ({0})".format(code)) - self.assertIn('buy milk', out) - self.assertIn('mow the lawn', out) + self.assertIn("buy milk", out) + self.assertIn("mow the lawn", out) def test_attribute_and_search_filter(self): """1468: Attribute and implicit search filter (project:home /lawn/)""" - code, out, err = self.t('list project:home /lawn/') + code, out, err = self.t("list project:home /lawn/") self.assertEqual(0, code, "Exit code was non-zero ({0})".format(code)) - self.assertNotIn('buy milk', out) - self.assertIn('mow the lawn', out) + self.assertNotIn("buy milk", out) + self.assertIn("mow the lawn", out) class TestBug1521(TestCase): @@ -1021,19 +1027,19 @@ class Test1634(TestCase): self.t = Task() # Setup some tasks due on 2015-07-07 - self.t('add due:2015-07-07T00:00:00 ON1') - self.t('add due:2015-07-07T14:34:56 ON2') - self.t('add due:2015-07-07T23:59:59 ON3') + self.t("add due:2015-07-07T00:00:00 ON1") + self.t("add due:2015-07-07T14:34:56 ON2") + self.t("add due:2015-07-07T23:59:59 ON3") # Setup some tasks not due on 2015-07-07 - self.t('add due:2015-07-06T23:59:59 OFF4') - self.t('add due:2015-07-08T00:00:00 OFF5') - self.t('add due:2015-07-08T00:00:01 OFF6') - self.t('add due:2015-07-06T00:00:00 OFF7') + self.t("add due:2015-07-06T23:59:59 OFF4") + self.t("add due:2015-07-08T00:00:00 OFF5") + self.t("add due:2015-07-08T00:00:01 OFF6") + self.t("add due:2015-07-06T00:00:00 OFF7") def test_due_match_not_exact(self): """1634: Test that due: matches any task that date.""" - code, out, err = self.t('due:2015-07-07 minimal') + code, out, err = self.t("due:2015-07-07 minimal") # Asswer that only tasks ON the date are listed. self.assertIn("ON1", out) @@ -1048,7 +1054,7 @@ class Test1634(TestCase): def test_due_not_match_not_exact(self): """1634: Test that due.not: does not match any task that date.""" - code, out, err = self.t('due.not:2015-07-07 minimal') + code, out, err = self.t("due.not:2015-07-07 minimal") # Assert that task ON the date are not listed. self.assertNotIn("ON1", out) @@ -1072,14 +1078,18 @@ class TestBug1915(TestCase): def test_complex_and_or_query_variant_one(self): """1915: Make sure parser handles complex and-or queries correctly (1)""" - code, out, err = self.t("rc.verbose:nothing '(project:A or project:B) and status:pending' all") + code, out, err = self.t( + "rc.verbose:nothing '(project:A or project:B) and status:pending' all" + ) self.assertIn("thingA", out) self.assertIn("thingB", out) self.assertNotIn("thingC", out) def test_complex_and_or_query_variant_two(self): """1915: Make sure parser handles complex and-or queries correctly (2)""" - code, out, err = self.t("rc.verbose:nothing '( project:A or project:B ) and status:pending' all") + code, out, err = self.t( + "rc.verbose:nothing '( project:A or project:B ) and status:pending' all" + ) self.assertIn("thingA", out) self.assertIn("thingB", out) self.assertNotIn("thingC", out) @@ -1087,7 +1097,9 @@ class TestBug1915(TestCase): @unittest.expectedFailure def test_complex_and_or_query_variant_three(self): """1915: Make sure parser handles complex and-or queries correctly (3)""" - code, out, err = self.t("rc.verbose:nothing 'status:pending and (project:A or project:B)' all") + code, out, err = self.t( + "rc.verbose:nothing 'status:pending and (project:A or project:B)' all" + ) self.assertIn("thingA", out) self.assertIn("thingB", out) self.assertNotIn("thingC", out) @@ -1095,28 +1107,36 @@ class TestBug1915(TestCase): @unittest.expectedFailure def test_complex_and_or_query_variant_four(self): """1915: Make sure parser handles complex and-or queries correctly (4)""" - code, out, err = self.t("rc.verbose:nothing 'status:pending and ( project:A or project:B )' all") + code, out, err = self.t( + "rc.verbose:nothing 'status:pending and ( project:A or project:B )' all" + ) self.assertIn("thingA", out) self.assertIn("thingB", out) self.assertNotIn("thingC", out) def test_complex_and_or_query_variant_five(self): """1915: Make sure parser handles complex and-or queries correctly (5)""" - code, out, err = self.t("rc.verbose:nothing status:pending and '(project:A or project:B)' all") + code, out, err = self.t( + "rc.verbose:nothing status:pending and '(project:A or project:B)' all" + ) self.assertIn("thingA", out) self.assertIn("thingB", out) self.assertNotIn("thingC", out) def test_complex_and_or_query_variant_six(self): """1915: Make sure parser handles complex and-or queries correctly (6)""" - code, out, err = self.t("rc.verbose:nothing status:pending and '( project:A or project:B )' all") + code, out, err = self.t( + "rc.verbose:nothing status:pending and '( project:A or project:B )' all" + ) self.assertIn("thingA", out) self.assertIn("thingB", out) self.assertNotIn("thingC", out) def test_complex_and_or_query_variant_seven(self): """1915: Make sure parser handles complex and-or queries correctly (7)""" - code, out, err = self.t("rc.verbose:nothing status:pending and \\( project:A or project:B \\) all") + code, out, err = self.t( + "rc.verbose:nothing status:pending and \\( project:A or project:B \\) all" + ) self.assertIn("thingA", out) self.assertIn("thingB", out) self.assertNotIn("thingC", out) @@ -1124,7 +1144,9 @@ class TestBug1915(TestCase): @unittest.expectedFailure def test_complex_and_or_query_variant_eight(self): """1915: Make sure parser handles complex and-or queries correctly (8)""" - code, out, err = self.t("rc.verbose:nothing status:pending and \\(project:A or project:B\\) all") + code, out, err = self.t( + "rc.verbose:nothing status:pending and \\(project:A or project:B\\) all" + ) self.assertIn("thingA", out) self.assertIn("thingB", out) self.assertNotIn("thingC", out) @@ -1136,11 +1158,11 @@ class Test2577(TestCase): def test_filtering_for_datetime_like(self): """2577: Check that filtering for datetime-like project names works""" - self.t('add one pro:sat') # looks like "saturday" - self.t('add two pro:whatever') + self.t("add one pro:sat") # looks like "saturday" + self.t("add two pro:whatever") # This should not fail (fails on 2.5.3) - code, out, err = self.t('pro:sat') + code, out, err = self.t("pro:sat") # Assert expected output, but the crucial part of this test is success # of the call above @@ -1149,6 +1171,7 @@ class Test2577(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/fontunderline.test.py b/test/fontunderline.test.py index 8b2b4c11e..626d6e1c0 100755 --- a/test/fontunderline.test.py +++ b/test/fontunderline.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -57,40 +58,57 @@ class TestUnderline(TestCase): # * When isatty (fileno (stdout)) is false, color is automatically disabled. def test_nocolor_noforce_nounderline(self): - code, out, err = self.t("1 info rc.color:off rc._forcecolor:off rc.fontunderline:off") + code, out, err = self.t( + "1 info rc.color:off rc._forcecolor:off rc.fontunderline:off" + ) self.assertIn("--------", out) def test_nocolor_noforce_underline(self): - code, out, err = self.t("1 info rc.color:off rc._forcecolor:off rc.fontunderline:on") + code, out, err = self.t( + "1 info rc.color:off rc._forcecolor:off rc.fontunderline:on" + ) self.assertIn("--------", out) def test_nocolor_force_nounderline(self): - code, out, err = self.t("1 info rc.color:off rc._forcecolor:on rc.fontunderline:off") + code, out, err = self.t( + "1 info rc.color:off rc._forcecolor:on rc.fontunderline:off" + ) self.assertIn("--------", out) def test_nocolor_force_underline(self): - code, out, err = self.t("1 info rc.color:off rc._forcecolor:on rc.fontunderline:on") + code, out, err = self.t( + "1 info rc.color:off rc._forcecolor:on rc.fontunderline:on" + ) self.assertNotIn("--------", out) def test_color_noforce_nounderline(self): - code, out, err = self.t("1 info rc.color:on rc._forcecolor:off rc.fontunderline:off") + code, out, err = self.t( + "1 info rc.color:on rc._forcecolor:off rc.fontunderline:off" + ) self.assertIn("--------", out) def test_color_noforce_underline(self): - code, out, err = self.t("1 info rc.color:on rc._forcecolor:off rc.fontunderline:on") + code, out, err = self.t( + "1 info rc.color:on rc._forcecolor:off rc.fontunderline:on" + ) self.assertIn("--------", out) def test_color_force_nounderline(self): - code, out, err = self.t("1 info rc.color:on rc._forcecolor:on rc.fontunderline:off") + code, out, err = self.t( + "1 info rc.color:on rc._forcecolor:on rc.fontunderline:off" + ) self.assertIn("--------", out) def test_color_force_underline(self): - code, out, err = self.t("1 info rc.color:on rc._forcecolor:on rc.fontunderline:on") + code, out, err = self.t( + "1 info rc.color:on rc._forcecolor:on rc.fontunderline:on" + ) self.assertNotIn("--------", out) if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/format.test.py b/test/format.test.py index 997aa452f..b1cf99c95 100755 --- a/test/format.test.py +++ b/test/format.test.py @@ -29,6 +29,7 @@ import sys import os import unittest import math + # Ensure python finds the local simpletap and basetest modules sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -61,11 +62,11 @@ class TestCountdown(TestCase): def test_countdown_up(self): """Verify countdown sorting: ascending""" - self.t.config("report.up.description", "countdown+ report") - self.t.config("report.up.columns", "id,due.countdown,description") - self.t.config("report.up.labels", "ID,Countdown,Description") - self.t.config("report.up.filter", "status:pending") - self.t.config("report.up.sort", "due+") + self.t.config("report.up.description", "countdown+ report") + self.t.config("report.up.columns", "id,due.countdown,description") + self.t.config("report.up.labels", "ID,Countdown,Description") + self.t.config("report.up.filter", "status:pending") + self.t.config("report.up.sort", "due+") code, out, err = self.t("up") self.assertRegex(out, " one\n.+ two\n") @@ -85,11 +86,11 @@ class TestCountdown(TestCase): def test_countdown_down(self): """Verify countdown sorting: descending""" - self.t.config("report.down.description", "countdown- report") - self.t.config("report.down.columns", "id,due.countdown,description") - self.t.config("report.down.labels", "ID,Countdown,Description") - self.t.config("report.down.filter", "status:pending") - self.t.config("report.down.sort", "due-") + self.t.config("report.down.description", "countdown- report") + self.t.config("report.down.columns", "id,due.countdown,description") + self.t.config("report.down.labels", "ID,Countdown,Description") + self.t.config("report.down.filter", "status:pending") + self.t.config("report.down.sort", "due-") code, out, err = self.t("down") self.assertRegex(out, " fifteen\n.+ fourteen\n") @@ -143,7 +144,9 @@ class TestBug101(TestCase): self.short_description = "A_task_description_" # Generate long string - self.long_description = self.short_description * int(math.ceil(float(self.width)/len(self.short_description))) + self.long_description = self.short_description * int( + math.ceil(float(self.width) / len(self.short_description)) + ) def test_short_no_count(self): """101: Check short description with no annotations""" @@ -164,7 +167,7 @@ class TestBug101(TestCase): """101: Check long description with no annotations""" self.t(("add", self.long_description)) code, out, err = self.t("bug101") - expected = self.long_description[:(self.width - 3)] + "..." + expected = self.long_description[: (self.width - 3)] + "..." self.assertIn(expected, out) def test_long_with_count(self): @@ -172,7 +175,7 @@ class TestBug101(TestCase): self.t(("add", self.long_description)) self.t("1 annotate 'A task annotation'") code, out, err = self.t("bug101") - expected = self.long_description[:(self.width - 7)] + "... [1]" + expected = self.long_description[: (self.width - 7)] + "... [1]" self.assertIn(expected, out) def test_long_with_double_digit_count(self): @@ -181,12 +184,13 @@ class TestBug101(TestCase): for i in range(10): self.t("1 annotate 'A task annotation'") code, out, err = self.t("bug101") - expected = self.long_description[:(self.width - 8)] + "... [10]" + expected = self.long_description[: (self.width - 8)] + "... [10]" self.assertIn(expected, out) if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/gc.test.py b/test/gc.test.py index 36681964b..2b3c0577e 100755 --- a/test/gc.test.py +++ b/test/gc.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -72,6 +73,7 @@ class TestGC(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/helpers.test.py b/test/helpers.test.py index 8dbc27c28..b28c8f6c8 100755 --- a/test/helpers.test.py +++ b/test/helpers.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -42,10 +43,10 @@ class TestZshAttributes(TestCase): def test_zsh_attributes_helper(self): """Ensure the _zshattributes command returns the expected format""" code, out, err = self.t("_zshattributes") - for line in out.split('\n'): - if line != '': - fields = line.split(':') - self.assertEqual(fields[0], fields[1]) + for line in out.split("\n"): + if line != "": + fields = line.split(":") + self.assertEqual(fields[0], fields[1]) class TestZshCompletion(TestCase): @@ -69,6 +70,7 @@ class TestAliasesCompletion(TestCase): """Aliases should be listed by '_aliases' not '_commands' or '_zshcommands' reported as bug 1043 """ + def setUp(self): self.t = Task() self.t.config("alias.samplealias", "long") @@ -131,6 +133,7 @@ class TestBug956(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/history.test.py b/test/history.test.py index 04f46b005..e2c5a7c40 100755 --- a/test/history.test.py +++ b/test/history.test.py @@ -28,11 +28,13 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) from basetest import Task, TestCase + class TestHistoryDaily(TestCase): def setUp(self): """Executed before each test in the class""" @@ -66,6 +68,7 @@ class TestHistoryDaily(TestCase): self.assertRegex(out, r"2015\s+January\s+2\s+\++X+\s") self.assertRegex(out, r"\s+February\s+2\s+\++X+\-+") + class TestHistoryWeekly(TestCase): def setUp(self): """Executed before each test in the class""" @@ -171,8 +174,10 @@ class TestHistoryAnnual(TestCase): self.assertRegex(out, r"2014\s+\++X+\s") self.assertRegex(out, r"2015\s+\++X+\-+") + if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/hooks.env.test.py b/test/hooks.env.test.py index ea9d91593..14eda273d 100755 --- a/test/hooks.env.test.py +++ b/test/hooks.env.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -42,28 +43,30 @@ class TestHooksOnLaunch(TestCase): def test_onlaunch_builtin_env(self): """on-launch-env - a well-behaved, successful, on-launch hook that echoes its env.""" - hookname = 'on-launch-good-env' + hookname = "on-launch-good-env" self.t.hooks.add_default(hookname, log=True) - code, out, err = self.t("version") # Arbitrary command that generates output. + code, out, err = self.t("version") # Arbitrary command that generates output. hook = self.t.hooks[hookname] hook.assertTriggeredCount(1) hook.assertExitcode(0) logs = hook.get_logs() - taskenv = {k:v for k, v in (line.split(":", 1) for line in logs["output"]["msgs"])} + taskenv = { + k: v for k, v in (line.split(":", 1) for line in logs["output"]["msgs"]) + } - self.assertEqual('api' in taskenv, True, 'api:...') - self.assertEqual('args' in taskenv, True, 'args:...') - self.assertEqual('command' in taskenv, True, 'command:...') - self.assertEqual('rc' in taskenv, True, 'rc:...') - self.assertEqual('data' in taskenv, True, 'data:...') - self.assertEqual('version' in taskenv, True, 'version:...') + self.assertEqual("api" in taskenv, True, "api:...") + self.assertEqual("args" in taskenv, True, "args:...") + self.assertEqual("command" in taskenv, True, "command:...") + self.assertEqual("rc" in taskenv, True, "rc:...") + self.assertEqual("data" in taskenv, True, "data:...") + self.assertEqual("version" in taskenv, True, "version:...") def test_onlaunch_builtin_env_diag(self): """Verify that 'diagnostics' can see hook details""" - hookname = 'on-launch-good-env' + hookname = "on-launch-good-env" self.t.hooks.add_default(hookname, log=True) code, out, err = self.t("diagnostics") @@ -71,7 +74,7 @@ class TestHooksOnLaunch(TestCase): def test_onlaunch_builtin_env_debug(self): """Verify that 'debug.hooks' shows hook details""" - hookname = 'on-launch-good-env' + hookname = "on-launch-good-env" self.t.hooks.add_default(hookname, log=True) code, out, err = self.t("version rc.debug.hooks:2") @@ -84,6 +87,7 @@ class TestHooksOnLaunch(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/hooks.on-add.test.py b/test/hooks.on-add.test.py index c63553752..011ebd86f 100755 --- a/test/hooks.on-add.test.py +++ b/test/hooks.on-add.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -42,7 +43,7 @@ class TestHooksOnAdd(TestCase): def test_onadd_builtin_accept(self): """on-add-accept - a well-behaved, successful, on-add hook.""" - hookname = 'on-add-accept' + hookname = "on-add-accept" self.t.hooks.add_default(hookname, log=True) code, out, err = self.t("add foo") @@ -59,7 +60,7 @@ class TestHooksOnAdd(TestCase): def test_onadd_builtin_accept_modify(self): """on-add-accept-modify - a well-behaved, successful, on-add hook, that modifies the added task.""" - hookname = 'on-add-modify' + hookname = "on-add-modify" self.t.hooks.add_default(hookname, log=True) code, out, err = self.t("add teh foo") @@ -76,7 +77,7 @@ class TestHooksOnAdd(TestCase): def test_onadd_builtin_reject(self): """on-add-reject - a well-behaved, failing, on-add hook.""" - hookname = 'on-add-reject' + hookname = "on-add-reject" self.t.hooks.add_default(hookname, log=True) code, out, err = self.t.runError("add foo") @@ -94,7 +95,7 @@ class TestHooksOnAdd(TestCase): def test_onadd_builtin_misbehave1(self): """on-add-misbehave1 - does not consume input.""" - hookname = 'on-add-misbehave1' + hookname = "on-add-misbehave1" self.t.hooks.add_default(hookname, log=True) code, out, err = self.t.runError("add foo") @@ -108,7 +109,7 @@ class TestHooksOnAdd(TestCase): def test_onadd_builtin_misbehave2(self): """on-add-misbehave2 - does not emit JSON.""" - hookname = 'on-add-misbehave2' + hookname = "on-add-misbehave2" self.t.hooks.add_default(hookname, log=True) code, out, err = self.t.runError("add foo") @@ -120,7 +121,7 @@ class TestHooksOnAdd(TestCase): def test_onadd_builtin_misbehave3(self): """on-add-misbehave3 - emits additional JSON.""" - hookname = 'on-add-misbehave3' + hookname = "on-add-misbehave3" self.t.hooks.add_default(hookname, log=True) code, out, err = self.t.runError("add foo") @@ -132,7 +133,7 @@ class TestHooksOnAdd(TestCase): def test_onadd_builtin_misbehave4(self): """on-add-misbehave4 - emits different task JSON.""" - hookname = 'on-add-misbehave4' + hookname = "on-add-misbehave4" self.t.hooks.add_default(hookname, log=True) code, out, err = self.t.runError("add foo") @@ -147,11 +148,11 @@ class TestHooksOnAdd(TestCase): def test_onadd_builtin_misbehave5(self): """on-add-misbehave5 - emits syntactically wrong JSON.""" - hookname = 'on-add-misbehave5' + hookname = "on-add-misbehave5" self.t.hooks.add_default(hookname, log=True) code, out, err = self.t.runError("add foo") - self.assertIn("Hook Error: JSON syntax error in: {\"}", err) + self.assertIn('Hook Error: JSON syntax error in: {"}', err) hook = self.t.hooks[hookname] hook.assertTriggeredCount(1) @@ -163,11 +164,14 @@ class TestHooksOnAdd(TestCase): def test_onadd_builtin_misbehave6(self): """on-add-misbehave6 - emits incomplete JSON.""" - hookname = 'on-add-misbehave6' + hookname = "on-add-misbehave6" self.t.hooks.add_default(hookname, log=True) code, out, err = self.t.runError("add foo") - self.assertIn("Hook Error: JSON Object missing 'uuid' attribute from hook script: on-add-misbehave6", err) + self.assertIn( + "Hook Error: JSON Object missing 'uuid' attribute from hook script: on-add-misbehave6", + err, + ) hook = self.t.hooks[hookname] hook.assertTriggeredCount(1) @@ -176,8 +180,10 @@ class TestHooksOnAdd(TestCase): logs = hook.get_logs() self.assertEqual(logs["output"]["msgs"][0], "FEEDBACK") + if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/hooks.on-exit.test.py b/test/hooks.on-exit.test.py index fe7e05b30..5673395ec 100755 --- a/test/hooks.on-exit.test.py +++ b/test/hooks.on-exit.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -42,7 +43,7 @@ class TestHooksOnExit(TestCase): def test_onexit_builtin_good(self): """on-exit-good - a well-behaved, successful, on-exit hook.""" - hookname = 'on-exit-good' + hookname = "on-exit-good" self.t.hooks.add_default(hookname, log=True) code, out, err = self.t("version") @@ -57,7 +58,7 @@ class TestHooksOnExit(TestCase): def test_onexit_builtin_good_gets_changed_tasks(self): """on-exit-good - a well-behaved, successful, on-exit hook.""" - hookname = 'on-exit-good' + hookname = "on-exit-good" self.t.hooks.add_default(hookname, log=True) code, out, err = self.t("add foo") @@ -73,7 +74,7 @@ class TestHooksOnExit(TestCase): def test_onexit_builtin_bad(self): """on-exit-bad - a well-behaved, failing, on-exit hook.""" - hookname = 'on-exit-bad' + hookname = "on-exit-bad" self.t.hooks.add_default(hookname, log=True) # Failing hook should prevent processing. @@ -89,7 +90,7 @@ class TestHooksOnExit(TestCase): def test_onexit_builtin_misbehave1(self): """on-exit-misbehave1 - Does not consume input.""" - hookname = 'on-exit-misbehave1' + hookname = "on-exit-misbehave1" self.t.hooks.add_default(hookname, log=True) # Failing hook should prevent processing. @@ -105,7 +106,7 @@ class TestHooksOnExit(TestCase): def test_onexit_builtin_misbehave2(self): """on-exit-misbehave2 - Emits unexpected JSON.""" - hookname = 'on-exit-misbehave2' + hookname = "on-exit-misbehave2" self.t.hooks.add_default(hookname, log=True) # Failing hook should prevent processing. @@ -119,8 +120,10 @@ class TestHooksOnExit(TestCase): logs = hook.get_logs() self.assertEqual(logs["output"]["msgs"][0], "FEEDBACK") + if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/hooks.on-launch.test.py b/test/hooks.on-launch.test.py index b89098d2e..731486d47 100755 --- a/test/hooks.on-launch.test.py +++ b/test/hooks.on-launch.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -42,7 +43,7 @@ class TestHooksOnLaunch(TestCase): def test_onlaunch_builtin_good(self): """on-launch-good - a well-behaved, successful, on-launch hook.""" - hookname = 'on-launch-good' + hookname = "on-launch-good" self.t.hooks.add_default(hookname, log=True) code, out, err = self.t("version") @@ -57,7 +58,7 @@ class TestHooksOnLaunch(TestCase): def test_onlaunch_builtin_bad(self): """on-launch-bad - a well-behaved, failing, on-launch hook.""" - hookname = 'on-launch-bad' + hookname = "on-launch-bad" self.t.hooks.add_default(hookname, log=True) # Failing hook should prevent processing. @@ -73,7 +74,7 @@ class TestHooksOnLaunch(TestCase): def test_onlaunch_builtin_misbehave1(self): """on-launch-misbehave1 - Hook kills itself.""" - hookname = 'on-launch-misbehave1' + hookname = "on-launch-misbehave1" self.t.hooks.add_default(hookname, log=True) # Failing hook should prevent processing. @@ -89,7 +90,7 @@ class TestHooksOnLaunch(TestCase): def test_onlaunch_builtin_misbehave2(self): """on-launch-misbehave2 - Hook emits unexpected JSON.""" - hookname = 'on-launch-misbehave2' + hookname = "on-launch-misbehave2" self.t.hooks.add_default(hookname, log=True) # Failing hook should prevent processing. @@ -103,8 +104,10 @@ class TestHooksOnLaunch(TestCase): logs = hook.get_logs() self.assertEqual(logs["output"]["msgs"][0], "FEEDBACK") + if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/hooks.on-modify.test.py b/test/hooks.on-modify.test.py index 2f8fea56e..e835eeb9a 100755 --- a/test/hooks.on-modify.test.py +++ b/test/hooks.on-modify.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -42,7 +43,7 @@ class TestHooksOnModify(TestCase): def test_onmodify_builtin_accept(self): """on-modify-accept - a well-behaved, successful, on-modify hook.""" - hookname = 'on-modify-accept' + hookname = "on-modify-accept" self.t.hooks.add_default(hookname, log=True) code, out, err = self.t("add foo") @@ -61,7 +62,7 @@ class TestHooksOnModify(TestCase): def test_onmodify_builtin_reject(self): """on-modify-reject - a well-behaved, failing, on-modify hook.""" - hookname = 'on-modify-reject' + hookname = "on-modify-reject" self.t.hooks.add_default(hookname, log=True) code, out, err = self.t("add foo") @@ -76,7 +77,7 @@ class TestHooksOnModify(TestCase): def test_onmodify_builtin_misbehave2(self): """on-modify-misbehave2 - does not emit JSON.""" - hookname = 'on-modify-misbehave2' + hookname = "on-modify-misbehave2" self.t.hooks.add_default(hookname, log=True) code, out, err = self.t("add foo") @@ -92,7 +93,7 @@ class TestHooksOnModify(TestCase): def test_onmodify_builtin_misbehave3(self): """on-modify-misbehave3 - emits additional JSON.""" - hookname = 'on-modify-misbehave3' + hookname = "on-modify-misbehave3" self.t.hooks.add_default(hookname, log=True) code, out, err = self.t("add foo") @@ -108,7 +109,7 @@ class TestHooksOnModify(TestCase): def test_onmodify_builtin_misbehave4(self): """on-modify-misbehave4 - emits different task JSON.""" - hookname = 'on-modify-misbehave4' + hookname = "on-modify-misbehave4" self.t.hooks.add_default(hookname, log=True) code, out, err = self.t("add foo") @@ -124,12 +125,12 @@ class TestHooksOnModify(TestCase): def test_onmodify_builtin_misbehave5(self): """on-modify-misbehave5 - emits syntactically wrong JSON.""" - hookname = 'on-modify-misbehave5' + hookname = "on-modify-misbehave5" self.t.hooks.add_default(hookname, log=True) code, out, err = self.t("add foo") code, out, err = self.t.runError("1 modify +tag") - self.assertIn("Hook Error: JSON syntax error in: {\"}", err) + self.assertIn('Hook Error: JSON syntax error in: {"}', err) hook = self.t.hooks[hookname] hook.assertTriggeredCount(1) @@ -140,12 +141,15 @@ class TestHooksOnModify(TestCase): def test_onmodify_builtin_misbehave6(self): """on-modify-misbehave6 - emits incomplete JSON.""" - hookname = 'on-modify-misbehave6' + hookname = "on-modify-misbehave6" self.t.hooks.add_default(hookname, log=True) code, out, err = self.t("add foo") code, out, err = self.t.runError("1 modify +tag") - self.assertIn("Hook Error: JSON Object missing 'uuid' attribute from hook script: on-modify-misbehave6", err) + self.assertIn( + "Hook Error: JSON Object missing 'uuid' attribute from hook script: on-modify-misbehave6", + err, + ) hook = self.t.hooks[hookname] hook.assertTriggeredCount(1) @@ -156,7 +160,7 @@ class TestHooksOnModify(TestCase): def test_onmodify_revert_changes(self): """on-modify-revert - revert all user modifications.""" - hookname = 'on-modify-revert' + hookname = "on-modify-revert" self.t.hooks.add_default(hookname, log=True) code, out, err = self.t("add foo") @@ -172,8 +176,10 @@ class TestHooksOnModify(TestCase): hook.assertTriggeredCount(1) hook.assertExitcode(0) + if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/hyphenate.test.py b/test/hyphenate.test.py index 33aa05a91..c2c7466a8 100755 --- a/test/hyphenate.test.py +++ b/test/hyphenate.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -39,8 +40,8 @@ class TestHyphenation(TestCase): """Executed before each test in the class""" self.t = Task() self.t.config("defaultwidth", "20") - self.t.config("detection", "0") - self.t.config("verbose", "nothing") + self.t.config("detection", "0") + self.t.config("verbose", "nothing") def test_hyphenation_on_space(self): """Split on space instead of hyphenating""" @@ -54,6 +55,7 @@ class TestHyphenation(TestCase): code, out, err = self.t("ls") self.assertIn(" 1 AAAAAAAAAABBBBBB-\n", out) + class TestBug804(TestCase): def setUp(self): """Executed before each test in the class""" @@ -61,10 +63,10 @@ class TestBug804(TestCase): def test_hyphenation(self): """Verify hyphenation is controllable""" - self.t.config("print.empty.columns", "1") - self.t.config("report.unittest.labels", "ID,Project,Pri,Description") + self.t.config("print.empty.columns", "1") + self.t.config("report.unittest.labels", "ID,Project,Pri,Description") self.t.config("report.unittest.columns", "id,project,priority,description") - self.t.config("report.unittest.filter", "status:pending") + self.t.config("report.unittest.filter", "status:pending") # Setup: Add a tasks, annotate with long word. self.t("add one") @@ -83,6 +85,7 @@ class TestBug804(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/ids.test.py b/test/ids.test.py index cf810056f..4dc30935e 100755 --- a/test/ids.test.py +++ b/test/ids.test.py @@ -29,6 +29,7 @@ import sys import os import tempfile import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -42,9 +43,9 @@ class TestIDs(TestCase): self.t = Task() self.t("add one +A +B") - self.t("add two +A" ) + self.t("add two +A") self.t("add three +A +B") - self.t("add four" ) + self.t("add four") self.t("add five +A +B") def test_ids_count_A(self): @@ -86,7 +87,8 @@ class TestIDs(TestCase): """_zshuuids +A""" code, out, err = self.t("_zshuuids +A") self.assertRegex( - out, "{0}:one\n{0}:two\n{0}:three\n{0}:five".format(UUID_REGEXP)) + out, "{0}:one\n{0}:two\n{0}:three\n{0}:five".format(UUID_REGEXP) + ) def test_ids_ranges(self): """Verify consecutive IDs are compressed into a range""" @@ -107,8 +109,8 @@ class TestIDMisParse(TestCase): def test_parse_numbers_as_ids_not_patterns(self): """Verify that numbers are parsed as IDs""" - self.t("add 2 two") # ID 1 - self.t("add 1 one") # ID 2 + self.t("add 2 two") # ID 1 + self.t("add 1 one") # ID 2 self.t("add 3 three") # ID 3 code, out, err = self.t("2 ls rc.verbose:nothing") @@ -124,11 +126,13 @@ class TestIDRangeParsing(TestCase): def generate_tasks(self, n): """Generates n tasks for testing purposes""" - with tempfile.NamedTemporaryFile(mode='w') as f: - f.write('\n'.join([f'{{"description": "test task {i+1}"}}' for i in range(n)])) + with tempfile.NamedTemporaryFile(mode="w") as f: + f.write( + "\n".join([f'{{"description": "test task {i+1}"}}' for i in range(n)]) + ) f.flush() # use a long timeout here, because import is quite slow - code, out, err = self.t(f'import {f.name}', timeout=100) + code, out, err = self.t(f"import {f.name}", timeout=100) def test_single_digit_range(self): """Test that parsing single digit ID range works""" @@ -167,6 +171,7 @@ class TestIDRangeParsing(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/import.test.py b/test/import.test.py index 8fcc9366a..7771345a3 100755 --- a/test/import.test.py +++ b/test/import.test.py @@ -29,6 +29,7 @@ import sys import os import unittest import json + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -179,7 +180,7 @@ class TestImport(TestCase): def test_import_newlines_whitespace(self): """JSON array with whitespace before and after names and values""" _data = """[ -{ "uuid":"a0000000-a000-a000-a000-a00000000000" , "description" : "zero" ,"project":"A", "status":"pending","entry":"1234567889" } , +{ "uuid":"a0000000-a000-a000-a000-a00000000000" , "description" : "zero" ,"project":"A", "status":"pending","entry":"1234567889" } , { "uuid":"a1111111-a111-a111-a111-a11111111111","description":"one","project":"B","status":"pending","entry":"1234567889"}, {"uuid":"a2222222-a222-a222-a222-a22222222222","description":"two","status":"completed","entry":"1234524689","end":"1234524690" } ]""" code, out, err = self.t("import", input=_data) @@ -210,15 +211,20 @@ class TestImport(TestCase): self.t("import", input=_data) _t = self.t.export("a0000000-a000-a000-a000-a00000000000")[0] - for _uuid in ["a1111111-a111-a111-a111-a11111111111","a2222222-a222-a222-a222-a22222222222"]: + for _uuid in [ + "a1111111-a111-a111-a111-a11111111111", + "a2222222-a222-a222-a222-a22222222222", + ]: self.assertTrue((_t["depends"][0] == _uuid) or (_t["depends"][1] == _uuid)) def test_import_same_task_twice(self): """Test import same task twice""" - _data = """{"uuid":"a1111111-a222-a333-a444-a55555555555","description":"data4"}""" + _data = ( + """{"uuid":"a1111111-a222-a333-a444-a55555555555","description":"data4"}""" + ) self.t("import", input=_data) code, out1, err = self.t("export") - self.t.faketime('+1s') + self.t.faketime("+1s") self.t("import", input=_data) code, out2, err = self.t("export") self.assertEqual(out1, out2) @@ -230,7 +236,9 @@ class TestImport(TestCase): {"uuid":"a0000000-a000-a000-a000-a00000000000","description":"second description"} ]""" _, _, err = self.t("import", input=_data) - self.assertIn("Input contains UUID 'a0000000-a000-a000-a000-a00000000000' 2 times", err) + self.assertIn( + "Input contains UUID 'a0000000-a000-a000-a000-a00000000000' 2 times", err + ) class TestImportExportRoundtrip(TestCase): @@ -239,8 +247,8 @@ class TestImportExportRoundtrip(TestCase): self.t2 = Task() for client in (self.t1, self.t2): - client.config("dateformat", "m/d/Y") - client.config("verbose", "0") + client.config("dateformat", "m/d/Y") + client.config("verbose", "0") client.config("defaultwidth", "100") def _validate_data(self, client): @@ -277,7 +285,7 @@ class TestImportValidate(TestCase): def test_import_empty_json(self): """Verify empty JSON is caught""" - j = '{}' + j = "{}" code, out, err = self.t.runError("import", input=j) self.assertIn("A task must have a description.", err) @@ -343,6 +351,7 @@ class TestBug1441(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/info.test.py b/test/info.test.py index 89679b8bd..4d6945936 100755 --- a/test/info.test.py +++ b/test/info.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -59,7 +60,9 @@ class TestInfoCommand(TestCase): self.t.config("urgency.user.keyword.foo.coefficient", "1.0") self.t.config("urgency.uda.u_one.coefficient", "1.0") - self.t("add foo project:P +tag priority:H start:now due:eom wait:eom scheduled:eom recur:P1M until:eoy u_one:now u_two:1day") + self.t( + "add foo project:P +tag priority:H start:now due:eom wait:eom scheduled:eom recur:P1M until:eoy u_one:now u_two:1day" + ) self.t("1 annotate bar", input="n\n") code, out, err = self.t("1 info") @@ -88,7 +91,10 @@ class TestInfoCommand(TestCase): self.assertIn("YEAR", out) self.assertIn("UDA", out) - self.assertRegex(out, r"UUID\s+[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}") + self.assertRegex( + out, + r"UUID\s+[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}", + ) self.assertRegex(out, r"Urgency\s+\d+(\.\d+)?") self.assertRegex(out, r"Priority\s+H") @@ -105,6 +111,7 @@ class TestInfoCommand(TestCase): self.assertRegex(out, r"U_ONE\s+\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}") self.assertRegex(out, r"U_TWO\s+P1D") + class TestBug425(TestCase): def setUp(self): self.t = Task() @@ -120,6 +127,7 @@ class TestBug425(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/lexer.test.cpp b/test/lexer.test.cpp index 43a8af3c0..cac825f17 100644 --- a/test/lexer.test.cpp +++ b/test/lexer.test.cpp @@ -27,574 +27,975 @@ #include // cmake.h include header must come first -#include -#include -#include -#include -#include #include #include +#include +#include +#include + +#include +#include //////////////////////////////////////////////////////////////////////////////// -int main (int, char**) -{ +int main(int, char**) { #ifdef PRODUCT_TASKWARRIOR - UnitTest t (1255); + UnitTest t(1255); #else - UnitTest t (1235); + UnitTest t(1235); #endif // Use same Datetime/Duraiton configuration as Context∴:staticInitialization. - Datetime::isoEnabled = true; - Datetime::standaloneDateEnabled = false; - Datetime::standaloneTimeEnabled = false; + Datetime::isoEnabled = true; + Datetime::standaloneDateEnabled = false; + Datetime::standaloneTimeEnabled = false; Duration::standaloneSecondsEnabled = false; - std::vector > tokens; + std::vector> tokens; std::string token; Lexer::Type type; // Feed in some attributes and types, so that the Lexer knows what a DOM // reference is. - Lexer::attributes["due"] = "date"; - Lexer::attributes["tags"] = "string"; + Lexer::attributes["due"] = "date"; + Lexer::attributes["tags"] = "string"; Lexer::attributes["description"] = "string"; // static bool Lexer::isBoundary (int, int); - t.ok (Lexer::isBoundary (' ', 'a'), "' ' --> 'a' = isBoundary"); - t.ok (Lexer::isBoundary ('a', ' '), "'a' --> ' ' = isBoundary"); - t.ok (Lexer::isBoundary (' ', '+'), "' ' --> '+' = isBoundary"); - t.ok (Lexer::isBoundary (' ', ','), "' ' --> ',' = isBoundary"); - t.notok (Lexer::isBoundary ('3', '4'), "'3' --> '4' = isBoundary"); - t.ok (Lexer::isBoundary ('(', '('), "'(' --> '(' = isBoundary"); - t.notok (Lexer::isBoundary ('r', 'd'), "'r' --> 'd' = isBoundary"); + t.ok(Lexer::isBoundary(' ', 'a'), "' ' --> 'a' = isBoundary"); + t.ok(Lexer::isBoundary('a', ' '), "'a' --> ' ' = isBoundary"); + t.ok(Lexer::isBoundary(' ', '+'), "' ' --> '+' = isBoundary"); + t.ok(Lexer::isBoundary(' ', ','), "' ' --> ',' = isBoundary"); + t.notok(Lexer::isBoundary('3', '4'), "'3' --> '4' = isBoundary"); + t.ok(Lexer::isBoundary('(', '('), "'(' --> '(' = isBoundary"); + t.notok(Lexer::isBoundary('r', 'd'), "'r' --> 'd' = isBoundary"); // static bool Lexer::wasQuoted (const std::string&); - t.notok (Lexer::wasQuoted (""), "'' --> !wasQuoted"); - t.notok (Lexer::wasQuoted ("foo"), "'foo' --> !wasQuoted"); - t.ok (Lexer::wasQuoted ("a b"), "'a b' --> wasQuoted"); - t.ok (Lexer::wasQuoted ("(a)"), "'(a)' --> wasQuoted"); + t.notok(Lexer::wasQuoted(""), "'' --> !wasQuoted"); + t.notok(Lexer::wasQuoted("foo"), "'foo' --> !wasQuoted"); + t.ok(Lexer::wasQuoted("a b"), "'a b' --> wasQuoted"); + t.ok(Lexer::wasQuoted("(a)"), "'(a)' --> wasQuoted"); // static bool Lexer::dequote (std::string&, const std::string& quotes = "'\""); token = "foo"; - Lexer::dequote (token); - t.is (token, "foo", "dequote foo --> foo"); + Lexer::dequote(token); + t.is(token, "foo", "dequote foo --> foo"); token = "'foo'"; - Lexer::dequote (token); - t.is (token, "foo", "dequote 'foo' --> foo"); + Lexer::dequote(token); + t.is(token, "foo", "dequote 'foo' --> foo"); token = "'o\\'clock'"; - Lexer::dequote (token); - t.is (token, "o\\'clock", "dequote 'o\\'clock' --> o\\'clock"); + Lexer::dequote(token); + t.is(token, "o\\'clock", "dequote 'o\\'clock' --> o\\'clock"); token = "abba"; - Lexer::dequote (token, "a"); - t.is (token, "bb", "dequote 'abba' (a) --> bb"); + Lexer::dequote(token, "a"); + t.is(token, "bb", "dequote 'abba' (a) --> bb"); // Should result in no tokens. - Lexer l0 (""); - t.notok (l0.token (token, type), "'' --> no tokens"); + Lexer l0(""); + t.notok(l0.token(token, type), "'' --> no tokens"); // Should result in no tokens. - Lexer l1 (" \t "); - t.notok (l1.token (token, type), "' \\t ' --> no tokens"); + Lexer l1(" \t "); + t.notok(l1.token(token, type), "' \\t ' --> no tokens"); // \u20ac = Euro symbol. - Lexer l2 (R"( one 'two \'three\''+456-(1.3*2 - 0x12) 1.2e-3.4 foo.bar and '\u20ac')"); + Lexer l2(R"( one 'two \'three\''+456-(1.3*2 - 0x12) 1.2e-3.4 foo.bar and '\u20ac')"); - tokens.clear (); - while (l2.token (token, type)) - { - std::cout << "# «" << token << "» " << Lexer::typeName (type) << "\n"; - tokens.emplace_back (token, type); + tokens.clear(); + while (l2.token(token, type)) { + std::cout << "# «" << token << "» " << Lexer::typeName(type) << "\n"; + tokens.emplace_back(token, type); } - t.is (tokens[0].first, "one", "tokens[0] = 'one'"); // 30 - t.is (Lexer::typeName (tokens[0].second), "identifier", "tokens[0] = identifier"); - t.is (tokens[1].first, "'two 'three''", "tokens[1] = 'two 'three''"); - t.is (Lexer::typeName (tokens[1].second), "string", "tokens[1] = string"); - t.is (tokens[2].first, "+", "tokens[2] = '+'"); - t.is (Lexer::typeName (tokens[2].second), "op", "tokens[2] = op"); - t.is (tokens[3].first, "456", "tokens[3] = '456'"); - t.is (Lexer::typeName (tokens[3].second), "number", "tokens[3] = number"); - t.is (tokens[4].first, "-", "tokens[4] = '-'"); - t.is (Lexer::typeName (tokens[4].second), "op", "tokens[4] = op"); - t.is (tokens[5].first, "(", "tokens[5] = '('"); // 40 - t.is (Lexer::typeName (tokens[5].second), "op", "tokens[5] = op"); - t.is (tokens[6].first, "1.3", "tokens[6] = '1.3'"); - t.is (Lexer::typeName (tokens[6].second), "number", "tokens[6] = number"); - t.is (tokens[7].first, "*", "tokens[7] = '*'"); - t.is (Lexer::typeName (tokens[7].second), "op", "tokens[7] = op"); - t.is (tokens[8].first, "2", "tokens[8] = '2'"); - t.is (Lexer::typeName (tokens[8].second), "number", "tokens[8] = number"); - t.is (tokens[9].first, "-", "tokens[9] = '-'"); - t.is (Lexer::typeName (tokens[9].second), "op", "tokens[9] = op"); - t.is (tokens[10].first, "0x12", "tokens[10] = '0x12'"); // 50 - t.is (Lexer::typeName (tokens[10].second), "hex", "tokens[10] = hex"); - t.is (tokens[11].first, ")", "tokens[11] = ')'"); - t.is (Lexer::typeName (tokens[11].second), "op", "tokens[11] = op"); - t.is (tokens[12].first, "1.2e-3.4", "tokens[12] = '1.2e-3.4'"); - t.is (Lexer::typeName (tokens[12].second), "number", "tokens[12] = number"); - t.is (tokens[13].first, "foo.bar", "tokens[13] = 'foo.bar'"); - t.is (Lexer::typeName (tokens[13].second), "identifier", "tokens[13] = identifier"); - t.is (tokens[14].first, "and", "tokens[14] = 'and'"); // 60 - t.is (Lexer::typeName (tokens[14].second), "op", "tokens[14] = op"); - t.is (tokens[15].first, "'€'", "tokens[15] = \\u20ac --> ''€''"); - t.is (Lexer::typeName (tokens[15].second), "string", "tokens[15] = string"); + t.is(tokens[0].first, "one", "tokens[0] = 'one'"); // 30 + t.is(Lexer::typeName(tokens[0].second), "identifier", "tokens[0] = identifier"); + t.is(tokens[1].first, "'two 'three''", "tokens[1] = 'two 'three''"); + t.is(Lexer::typeName(tokens[1].second), "string", "tokens[1] = string"); + t.is(tokens[2].first, "+", "tokens[2] = '+'"); + t.is(Lexer::typeName(tokens[2].second), "op", "tokens[2] = op"); + t.is(tokens[3].first, "456", "tokens[3] = '456'"); + t.is(Lexer::typeName(tokens[3].second), "number", "tokens[3] = number"); + t.is(tokens[4].first, "-", "tokens[4] = '-'"); + t.is(Lexer::typeName(tokens[4].second), "op", "tokens[4] = op"); + t.is(tokens[5].first, "(", "tokens[5] = '('"); // 40 + t.is(Lexer::typeName(tokens[5].second), "op", "tokens[5] = op"); + t.is(tokens[6].first, "1.3", "tokens[6] = '1.3'"); + t.is(Lexer::typeName(tokens[6].second), "number", "tokens[6] = number"); + t.is(tokens[7].first, "*", "tokens[7] = '*'"); + t.is(Lexer::typeName(tokens[7].second), "op", "tokens[7] = op"); + t.is(tokens[8].first, "2", "tokens[8] = '2'"); + t.is(Lexer::typeName(tokens[8].second), "number", "tokens[8] = number"); + t.is(tokens[9].first, "-", "tokens[9] = '-'"); + t.is(Lexer::typeName(tokens[9].second), "op", "tokens[9] = op"); + t.is(tokens[10].first, "0x12", "tokens[10] = '0x12'"); // 50 + t.is(Lexer::typeName(tokens[10].second), "hex", "tokens[10] = hex"); + t.is(tokens[11].first, ")", "tokens[11] = ')'"); + t.is(Lexer::typeName(tokens[11].second), "op", "tokens[11] = op"); + t.is(tokens[12].first, "1.2e-3.4", "tokens[12] = '1.2e-3.4'"); + t.is(Lexer::typeName(tokens[12].second), "number", "tokens[12] = number"); + t.is(tokens[13].first, "foo.bar", "tokens[13] = 'foo.bar'"); + t.is(Lexer::typeName(tokens[13].second), "identifier", "tokens[13] = identifier"); + t.is(tokens[14].first, "and", "tokens[14] = 'and'"); // 60 + t.is(Lexer::typeName(tokens[14].second), "op", "tokens[14] = op"); + t.is(tokens[15].first, "'€'", "tokens[15] = \\u20ac --> ''€''"); + t.is(Lexer::typeName(tokens[15].second), "string", "tokens[15] = string"); // Test for numbers that are no longer ISO-8601 dates. - Lexer l3 ("1 12 123 1234 12345 123456 1234567"); - tokens.clear (); - while (l3.token (token, type)) - { - std::cout << "# «" << token << "» " << Lexer::typeName (type) << "\n"; - tokens.emplace_back (token, type); + Lexer l3("1 12 123 1234 12345 123456 1234567"); + tokens.clear(); + while (l3.token(token, type)) { + std::cout << "# «" << token << "» " << Lexer::typeName(type) << "\n"; + tokens.emplace_back(token, type); } - t.is ((int)tokens.size (), 7, "7 tokens"); - t.is (tokens[0].first, "1", "tokens[0] == '1'"); - t.is ((int) tokens[0].second, (int) Lexer::Type::number, "tokens[0] == Type::number"); - t.is (tokens[1].first, "12", "tokens[1] == '12'"); - t.is ((int) tokens[1].second, (int) Lexer::Type::number, "tokens[1] == Type::number"); - t.is (tokens[2].first, "123", "tokens[2] == '123'"); - t.is ((int) tokens[2].second, (int) Lexer::Type::number, "tokens[2] == Type::number"); // 70 - t.is (tokens[3].first, "1234", "tokens[3] == '1234'"); - t.is ((int) tokens[3].second, (int) Lexer::Type::number, "tokens[3] == Type::number"); - t.is (tokens[4].first, "12345", "tokens[4] == '12345'"); - t.is ((int) tokens[4].second, (int) Lexer::Type::number, "tokens[4] == Type::number"); - t.is (tokens[5].first, "123456", "tokens[5] == '123456'"); - t.is ((int) tokens[5].second, (int) Lexer::Type::number, "tokens[5] == Type::number"); - t.is (tokens[6].first, "1234567", "tokens[6] == '1234567'"); - t.is ((int) tokens[6].second, (int) Lexer::Type::number, "tokens[6] == Type::number"); + t.is((int)tokens.size(), 7, "7 tokens"); + t.is(tokens[0].first, "1", "tokens[0] == '1'"); + t.is((int)tokens[0].second, (int)Lexer::Type::number, "tokens[0] == Type::number"); + t.is(tokens[1].first, "12", "tokens[1] == '12'"); + t.is((int)tokens[1].second, (int)Lexer::Type::number, "tokens[1] == Type::number"); + t.is(tokens[2].first, "123", "tokens[2] == '123'"); + t.is((int)tokens[2].second, (int)Lexer::Type::number, "tokens[2] == Type::number"); // 70 + t.is(tokens[3].first, "1234", "tokens[3] == '1234'"); + t.is((int)tokens[3].second, (int)Lexer::Type::number, "tokens[3] == Type::number"); + t.is(tokens[4].first, "12345", "tokens[4] == '12345'"); + t.is((int)tokens[4].second, (int)Lexer::Type::number, "tokens[4] == Type::number"); + t.is(tokens[5].first, "123456", "tokens[5] == '123456'"); + t.is((int)tokens[5].second, (int)Lexer::Type::number, "tokens[5] == Type::number"); + t.is(tokens[6].first, "1234567", "tokens[6] == '1234567'"); + t.is((int)tokens[6].second, (int)Lexer::Type::number, "tokens[6] == Type::number"); // void split (std::vector&, const std::string&); std::string unsplit = " ( A or B ) "; - std::vector items; - items = Lexer::split (unsplit); - t.is (items.size (), (size_t) 5, "split ' ( A or B ) '"); - t.is (items[0], "(", "split ' ( A or B ) ' -> [0] '('"); - t.is (items[1], "A", "split ' ( A or B ) ' -> [1] 'A'"); - t.is (items[2], "or", "split ' ( A or B ) ' -> [2] 'or'"); - t.is (items[3], "B", "split ' ( A or B ) ' -> [3] 'B'"); - t.is (items[4], ")", "split ' ( A or B ) ' -> [4] ')'"); + std::vector items; + items = Lexer::split(unsplit); + t.is(items.size(), (size_t)5, "split ' ( A or B ) '"); + t.is(items[0], "(", "split ' ( A or B ) ' -> [0] '('"); + t.is(items[1], "A", "split ' ( A or B ) ' -> [1] 'A'"); + t.is(items[2], "or", "split ' ( A or B ) ' -> [2] 'or'"); + t.is(items[3], "B", "split ' ( A or B ) ' -> [3] 'B'"); + t.is(items[4], ")", "split ' ( A or B ) ' -> [4] ')'"); // Test simple mode with contrived tokens that ordinarily split. unsplit = " +-* a+b 12.3e4 'c d'"; - items = Lexer::split (unsplit); - t.is (items.size (), (size_t) 8, "split ' +-* a+b 12.3e4 'c d''"); - t.is (items[0], "+", "split ' +-* a+b 12.3e4 'c d'' -> [0] '+'"); - t.is (items[1], "-", "split ' +-* a+b 12.3e4 'c d'' -> [1] '-'"); - t.is (items[2], "*", "split ' +-* a+b 12.3e4 'c d'' -> [2] '*'"); - t.is (items[3], "a", "split ' +-* a+b 12.3e4 'c d'' -> [3] 'a'"); - t.is (items[4], "+", "split ' +-* a+b 12.3e4 'c d'' -> [4] '+'"); - t.is (items[5], "b", "split ' +-* a+b 12.3e4 'c d'' -> [5] 'b'"); - t.is (items[6], "12.3e4", "split ' +-* a+b 12.3e4 'c d'' -> [6] '12.3e4'"); - t.is (items[7], "'c d'", "split ' +-* a+b 12.3e4 'c d'' -> [7] ''c d''"); + items = Lexer::split(unsplit); + t.is(items.size(), (size_t)8, "split ' +-* a+b 12.3e4 'c d''"); + t.is(items[0], "+", "split ' +-* a+b 12.3e4 'c d'' -> [0] '+'"); + t.is(items[1], "-", "split ' +-* a+b 12.3e4 'c d'' -> [1] '-'"); + t.is(items[2], "*", "split ' +-* a+b 12.3e4 'c d'' -> [2] '*'"); + t.is(items[3], "a", "split ' +-* a+b 12.3e4 'c d'' -> [3] 'a'"); + t.is(items[4], "+", "split ' +-* a+b 12.3e4 'c d'' -> [4] '+'"); + t.is(items[5], "b", "split ' +-* a+b 12.3e4 'c d'' -> [5] 'b'"); + t.is(items[6], "12.3e4", "split ' +-* a+b 12.3e4 'c d'' -> [6] '12.3e4'"); + t.is(items[7], "'c d'", "split ' +-* a+b 12.3e4 'c d'' -> [7] ''c d''"); - // static bool decomposePair (const std::string&, std::string&, std::string&, std::string&, std::string&); - // 2 * 4 * 2 * 5 = 80 tests. + // static bool decomposePair (const std::string&, std::string&, std::string&, std::string&, + // std::string&); 2 * 4 * 2 * 5 = 80 tests. std::string outName, outMod, outValue, outSep; - for (auto& name : {"name"}) - { - for (auto& mod : {"", "mod"}) - { - for (auto& sep : {":", "=", "::", ":="}) - { - for (auto& value : {"", "value", "a:b", "a::b", "a=b", "a:=b"}) - { - std::string input = std::string ("name") + (strlen (mod) ? "." : "") + mod + sep + value; - t.ok (Lexer::decomposePair (input, outName, outMod, outSep, outValue), "decomposePair '" + input + "' --> true"); - t.is (name, outName, " '" + input + "' --> name '" + name + "'"); - t.is (mod, outMod, " '" + input + "' --> mod '" + mod + "'"); - t.is (value, outValue, " '" + input + "' --> value '" + value + "'"); - t.is (sep, outSep, " '" + input + "' --> sep '" + sep + "'"); + for (auto& name : {"name"}) { + for (auto& mod : {"", "mod"}) { + for (auto& sep : {":", "=", "::", ":="}) { + for (auto& value : {"", "value", "a:b", "a::b", "a=b", "a:=b"}) { + std::string input = std::string("name") + (strlen(mod) ? "." : "") + mod + sep + value; + t.ok(Lexer::decomposePair(input, outName, outMod, outSep, outValue), + "decomposePair '" + input + "' --> true"); + t.is(name, outName, " '" + input + "' --> name '" + name + "'"); + t.is(mod, outMod, " '" + input + "' --> mod '" + mod + "'"); + t.is(value, outValue, " '" + input + "' --> value '" + value + "'"); + t.is(sep, outSep, " '" + input + "' --> sep '" + sep + "'"); } } } } - // static bool readWord (const std::string&, const std::string&, std::string::size_type&, std::string&); + // static bool readWord (const std::string&, const std::string&, std::string::size_type&, + // std::string&); std::string::size_type cursor = 0; std::string word; - t.ok (Lexer::readWord ("'one two'", "'\"", cursor, word), "readWord ''one two'' --> true"); - t.is (word, "'one two'", " word '" + word + "'"); - t.is ((int)cursor, 9, " cursor"); + t.ok(Lexer::readWord("'one two'", "'\"", cursor, word), "readWord ''one two'' --> true"); + t.is(word, "'one two'", " word '" + word + "'"); + t.is((int)cursor, 9, " cursor"); // Unterminated quoted string is invalid. cursor = 0; - t.notok (Lexer::readWord ("'one", "'\"", cursor, word), "readWord ''one' --> false"); + t.notok(Lexer::readWord("'one", "'\"", cursor, word), "readWord ''one' --> false"); // static bool readWord (const std::string&, std::string::size_type&, std::string&); cursor = 0; - t.ok (Lexer::readWord ("input", cursor, word), "readWord 'input' --> true"); - t.is (word, "input", " word '" + word + "'"); - t.is ((int)cursor, 5, " cursor"); + t.ok(Lexer::readWord("input", cursor, word), "readWord 'input' --> true"); + t.is(word, "input", " word '" + word + "'"); + t.is((int)cursor, 5, " cursor"); cursor = 0; - t.ok (Lexer::readWord ("one\\ two", cursor, word), "readWord 'one\\ two' --> true"); - t.is (word, "one two", " word '" + word + "'"); - t.is ((int)cursor, 8, " cursor"); + t.ok(Lexer::readWord("one\\ two", cursor, word), "readWord 'one\\ two' --> true"); + t.is(word, "one two", " word '" + word + "'"); + t.is((int)cursor, 8, " cursor"); cursor = 0; - t.ok (Lexer::readWord ("\\u20A43", cursor, word), "readWord '\\u20A43' --> true"); - t.is (word, "₤3", " word '" + word + "'"); - t.is ((int)cursor, 7, " cursor"); + t.ok(Lexer::readWord("\\u20A43", cursor, word), "readWord '\\u20A43' --> true"); + t.is(word, "₤3", " word '" + word + "'"); + t.is((int)cursor, 7, " cursor"); cursor = 0; - t.ok (Lexer::readWord ("U+20AC4", cursor, word), "readWord '\\u20AC4' --> true"); - t.is (word, "€4", " word '" + word + "'"); - t.is ((int)cursor, 7, " cursor"); + t.ok(Lexer::readWord("U+20AC4", cursor, word), "readWord '\\u20AC4' --> true"); + t.is(word, "€4", " word '" + word + "'"); + t.is((int)cursor, 7, " cursor"); std::string text = "one 'two' three\\ four"; cursor = 0; - t.ok (Lexer::readWord (text, cursor, word), R"(readWord "one 'two' three\ four" --> true)"); - t.is (word, "one", " word '" + word + "'"); + t.ok(Lexer::readWord(text, cursor, word), R"(readWord "one 'two' three\ four" --> true)"); + t.is(word, "one", " word '" + word + "'"); cursor++; - t.ok (Lexer::readWord (text, cursor, word), R"(readWord "one 'two' three\ four" --> true)"); - t.is (word, "'two'", " word '" + word + "'"); + t.ok(Lexer::readWord(text, cursor, word), R"(readWord "one 'two' three\ four" --> true)"); + t.is(word, "'two'", " word '" + word + "'"); cursor++; - t.ok (Lexer::readWord (text, cursor, word), R"(readWord "one 'two' three\ four" --> true)"); - t.is (word, "three four", " word '" + word + "'"); + t.ok(Lexer::readWord(text, cursor, word), R"(readWord "one 'two' three\ four" --> true)"); + t.is(word, "three four", " word '" + word + "'"); text = "one "; cursor = 0; - t.ok (Lexer::readWord (text, cursor, word), "readWord \"one \" --> true"); - t.is (word, "one", " word '" + word + "'"); + t.ok(Lexer::readWord(text, cursor, word), "readWord \"one \" --> true"); + t.is(word, "one", " word '" + word + "'"); // bool isLiteral (const std::string&, bool, bool); - Lexer l4 ("one.two"); - t.notok (l4.isLiteral("zero", false, false), "isLiteral 'one.two' --> false"); - t.ok (l4.isLiteral("one", false, false), "isLiteral 'one.two' --> 'one'"); - t.ok (l4.isLiteral(".", false, false), "isLiteral 'one.two' --> '.'"); - t.ok (l4.isLiteral("two", false, true), "isLiteral 'one.two' --> 'two'"); + Lexer l4("one.two"); + t.notok(l4.isLiteral("zero", false, false), "isLiteral 'one.two' --> false"); + t.ok(l4.isLiteral("one", false, false), "isLiteral 'one.two' --> 'one'"); + t.ok(l4.isLiteral(".", false, false), "isLiteral 'one.two' --> '.'"); + t.ok(l4.isLiteral("two", false, true), "isLiteral 'one.two' --> 'two'"); - Lexer l5 ("wonder"); - t.notok (l5.isLiteral ("wonderful", false, false), "isLiteral 'wonderful' != 'wonder' without abbreviation"); - t.ok (l5.isLiteral ("wonderful", true, false), "isLiteral 'wonderful' == 'wonder' with abbreviation"); + Lexer l5("wonder"); + t.notok(l5.isLiteral("wonderful", false, false), + "isLiteral 'wonderful' != 'wonder' without abbreviation"); + t.ok(l5.isLiteral("wonderful", true, false), + "isLiteral 'wonderful' == 'wonder' with abbreviation"); // bool isOneOf (const std::string&, bool, bool); - Lexer l6 ("Grumpy."); - std::vector dwarves = {"Sneezy", "Doc", "Bashful", "Grumpy", "Happy", "Sleepy", "Dopey"}; - t.notok (l6.isOneOf (dwarves, false, true), "isOneof ('Grumpy', true) --> false"); - t.ok (l6.isOneOf (dwarves, false, false), "isOneOf ('Grumpy', false) --> true"); + Lexer l6("Grumpy."); + std::vector dwarves = {"Sneezy", "Doc", "Bashful", "Grumpy", + "Happy", "Sleepy", "Dopey"}; + t.notok(l6.isOneOf(dwarves, false, true), "isOneof ('Grumpy', true) --> false"); + t.ok(l6.isOneOf(dwarves, false, false), "isOneOf ('Grumpy', false) --> true"); // static std::string::size_type commonLength (const std::string&, const std::string&); - t.is ((int)Lexer::commonLength ("", ""), 0, "commonLength '' : '' --> 0"); - t.is ((int)Lexer::commonLength ("a", "a"), 1, "commonLength 'a' : 'a' --> 1"); - t.is ((int)Lexer::commonLength ("abcde", "abcde"), 5, "commonLength 'abcde' : 'abcde' --> 5"); - t.is ((int)Lexer::commonLength ("abc", ""), 0, "commonLength 'abc' : '' --> 0"); - t.is ((int)Lexer::commonLength ("abc", "def"), 0, "commonLength 'abc' : 'def' --> 0"); - t.is ((int)Lexer::commonLength ("foobar", "foo"), 3, "commonLength 'foobar' : 'foo' --> 3"); - t.is ((int)Lexer::commonLength ("foo", "foobar"), 3, "commonLength 'foo' : 'foobar' --> 3"); + t.is((int)Lexer::commonLength("", ""), 0, "commonLength '' : '' --> 0"); + t.is((int)Lexer::commonLength("a", "a"), 1, "commonLength 'a' : 'a' --> 1"); + t.is((int)Lexer::commonLength("abcde", "abcde"), 5, "commonLength 'abcde' : 'abcde' --> 5"); + t.is((int)Lexer::commonLength("abc", ""), 0, "commonLength 'abc' : '' --> 0"); + t.is((int)Lexer::commonLength("abc", "def"), 0, "commonLength 'abc' : 'def' --> 0"); + t.is((int)Lexer::commonLength("foobar", "foo"), 3, "commonLength 'foobar' : 'foo' --> 3"); + t.is((int)Lexer::commonLength("foo", "foobar"), 3, "commonLength 'foo' : 'foobar' --> 3"); - // static std::string::size_type commonLength (const std::string&, std::string::size_type, const std::string&, std::string::size_type); - t.is ((int)Lexer::commonLength ("wonder", 0, "prowonderbread", 3), 6, "'wonder'+0 : 'prowonderbread'+3 --> 6"); + // static std::string::size_type commonLength (const std::string&, std::string::size_type, const + // std::string&, std::string::size_type); + t.is((int)Lexer::commonLength("wonder", 0, "prowonderbread", 3), 6, + "'wonder'+0 : 'prowonderbread'+3 --> 6"); - // Test all Lexer types. - #define NO {"",Lexer::Type::word} - struct - { +// Test all Lexer types. +#define NO {"", Lexer::Type::word} + struct { const char* input; - struct - { + struct { const char* token; Lexer::Type type; bool expfail_token = false; bool expfail_type = false; } results[5]; - } lexerTests[] = - { - // Pattern - { "/foo/", { { "/foo/", Lexer::Type::pattern }, NO, NO, NO, NO }, }, - { "/a\\/b/", { { "/a\\/b/", Lexer::Type::pattern }, NO, NO, NO, NO }, }, - { "/'/", { { "/'/", Lexer::Type::pattern }, NO, NO, NO, NO }, }, + } lexerTests[] = { + // Pattern + { + "/foo/", + {{"/foo/", Lexer::Type::pattern}, NO, NO, NO, NO}, + }, + { + "/a\\/b/", + {{"/a\\/b/", Lexer::Type::pattern}, NO, NO, NO, NO}, + }, + { + "/'/", + {{"/'/", Lexer::Type::pattern}, NO, NO, NO, NO}, + }, - // Substitution - { "/from/to/g", { { "/from/to/g", Lexer::Type::substitution }, NO, NO, NO, NO }, }, - { "/from/to/", { { "/from/to/", Lexer::Type::substitution }, NO, NO, NO, NO }, }, + // Substitution + { + "/from/to/g", + {{"/from/to/g", Lexer::Type::substitution}, NO, NO, NO, NO}, + }, + { + "/from/to/", + {{"/from/to/", Lexer::Type::substitution}, NO, NO, NO, NO}, + }, - // Tag - { "+tag", { { "+tag", Lexer::Type::tag }, NO, NO, NO, NO }, }, - { "-tag", { { "-tag", Lexer::Type::tag }, NO, NO, NO, NO }, }, - { "+@tag", { { "+@tag", Lexer::Type::tag }, NO, NO, NO, NO }, }, + // Tag + { + "+tag", + {{"+tag", Lexer::Type::tag}, NO, NO, NO, NO}, + }, + { + "-tag", + {{"-tag", Lexer::Type::tag}, NO, NO, NO, NO}, + }, + { + "+@tag", + {{"+@tag", Lexer::Type::tag}, NO, NO, NO, NO}, + }, - // Path - { "/long/path/to/file.txt", { { "/long/path/to/file.txt", Lexer::Type::path }, NO, NO, NO, NO }, }, + // Path + { + "/long/path/to/file.txt", + {{"/long/path/to/file.txt", Lexer::Type::path}, NO, NO, NO, NO}, + }, - // Word - { "1.foo.bar", { { "1.foo.bar", Lexer::Type::word }, NO, NO, NO, NO }, }, + // Word + { + "1.foo.bar", + {{"1.foo.bar", Lexer::Type::word}, NO, NO, NO, NO}, + }, - // Identifier - { "foo", { { "foo", Lexer::Type::identifier }, NO, NO, NO, NO }, }, - { "Çirçös", { { "Çirçös", Lexer::Type::identifier }, NO, NO, NO, NO }, }, - { "☺", { { "☺", Lexer::Type::identifier }, NO, NO, NO, NO }, }, - { "name", { { "name", Lexer::Type::identifier }, NO, NO, NO, NO }, }, - { "f1", { { "f1", Lexer::Type::identifier }, NO, NO, NO, NO }, }, - { "foo.bar", { { "foo.bar", Lexer::Type::identifier }, NO, NO, NO, NO }, }, - { "a1a1a1a1_a1a1_a1a1_a1a1_a1a1a1a1a1a1", { { "a1a1a1a1_a1a1_a1a1_a1a1_a1a1a1a1a1a1", Lexer::Type::identifier }, NO, NO, NO, NO }, }, + // Identifier + { + "foo", + {{"foo", Lexer::Type::identifier}, NO, NO, NO, NO}, + }, + { + "Çirçös", + {{"Çirçös", Lexer::Type::identifier}, NO, NO, NO, NO}, + }, + { + "☺", + {{"☺", Lexer::Type::identifier}, NO, NO, NO, NO}, + }, + { + "name", + {{"name", Lexer::Type::identifier}, NO, NO, NO, NO}, + }, + { + "f1", + {{"f1", Lexer::Type::identifier}, NO, NO, NO, NO}, + }, + { + "foo.bar", + {{"foo.bar", Lexer::Type::identifier}, NO, NO, NO, NO}, + }, + { + "a1a1a1a1_a1a1_a1a1_a1a1_a1a1a1a1a1a1", + {{"a1a1a1a1_a1a1_a1a1_a1a1_a1a1a1a1a1a1", Lexer::Type::identifier}, NO, NO, NO, NO}, + }, - // Word that starts wih 'or', which is an operator, but should be ignored. - { "ordinary", { { "ordinary", Lexer::Type::identifier }, NO, NO, NO, NO }, }, + // Word that starts wih 'or', which is an operator, but should be ignored. + { + "ordinary", + {{"ordinary", Lexer::Type::identifier}, NO, NO, NO, NO}, + }, - // DOM - { "due", { { "due", Lexer::Type::dom }, NO, NO, NO, NO }, }, - { "123.tags", { { "123.tags", Lexer::Type::dom }, NO, NO, NO, NO }, }, - { "123.tags.PENDING", { { "123.tags.PENDING", Lexer::Type::dom }, NO, NO, NO, NO }, }, - { "123.description", { { "123.description", Lexer::Type::dom }, NO, NO, NO, NO }, }, - { "123.annotations.1.description", { { "123.annotations.1.description", Lexer::Type::dom }, NO, NO, NO, NO }, }, - { "123.annotations.1.entry", { { "123.annotations.1.entry", Lexer::Type::dom }, NO, NO, NO, NO }, }, - { "123.annotations.1.entry.year", { { "123.annotations.1.entry.year", Lexer::Type::dom }, NO, NO, NO, NO }, }, - { "a360fc44-315c-4366-b70c-ea7e7520b749.due", { { "a360fc44-315c-4366-b70c-ea7e7520b749.due", Lexer::Type::dom }, NO, NO, NO, NO }, }, - { "12345678-1234-1234-1234-123456789012.due", { { "12345678-1234-1234-1234-123456789012.due", Lexer::Type::dom }, NO, NO, NO, NO }, }, - { "system.os", { { "system.os", Lexer::Type::dom }, NO, NO, NO, NO }, }, - { "rc.foo", { { "rc.foo", Lexer::Type::dom }, NO, NO, NO, NO }, }, + // DOM + { + "due", + {{"due", Lexer::Type::dom}, NO, NO, NO, NO}, + }, + { + "123.tags", + {{"123.tags", Lexer::Type::dom}, NO, NO, NO, NO}, + }, + { + "123.tags.PENDING", + {{"123.tags.PENDING", Lexer::Type::dom}, NO, NO, NO, NO}, + }, + { + "123.description", + {{"123.description", Lexer::Type::dom}, NO, NO, NO, NO}, + }, + { + "123.annotations.1.description", + {{"123.annotations.1.description", Lexer::Type::dom}, NO, NO, NO, NO}, + }, + { + "123.annotations.1.entry", + {{"123.annotations.1.entry", Lexer::Type::dom}, NO, NO, NO, NO}, + }, + { + "123.annotations.1.entry.year", + {{"123.annotations.1.entry.year", Lexer::Type::dom}, NO, NO, NO, NO}, + }, + { + "a360fc44-315c-4366-b70c-ea7e7520b749.due", + {{"a360fc44-315c-4366-b70c-ea7e7520b749.due", Lexer::Type::dom}, NO, NO, NO, NO}, + }, + { + "12345678-1234-1234-1234-123456789012.due", + {{"12345678-1234-1234-1234-123456789012.due", Lexer::Type::dom}, NO, NO, NO, NO}, + }, + { + "system.os", + {{"system.os", Lexer::Type::dom}, NO, NO, NO, NO}, + }, + { + "rc.foo", + {{"rc.foo", Lexer::Type::dom}, NO, NO, NO, NO}, + }, - // URL - { "http://example.com", { { "http://example.com", Lexer::Type::url }, NO, NO, NO, NO }, }, - { "https://foo.example.com", { { "https://foo.example.com", Lexer::Type::url }, NO, NO, NO, NO }, }, + // URL + { + "http://example.com", + {{"http://example.com", Lexer::Type::url}, NO, NO, NO, NO}, + }, + { + "https://foo.example.com", + {{"https://foo.example.com", Lexer::Type::url}, NO, NO, NO, NO}, + }, - // String - { "'one two'", { { "'one two'", Lexer::Type::string }, NO, NO, NO, NO }, }, - { "\"three\"", { { "\"three\"", Lexer::Type::string }, NO, NO, NO, NO }, }, - { "'\\''", { { "'''", Lexer::Type::string }, NO, NO, NO, NO }, }, - {R"("\"")", { {R"(""")", Lexer::Type::string }, NO, NO, NO, NO }, }, - { "\"\tfoo\t\"", { { "\"\tfoo\t\"", Lexer::Type::string }, NO, NO, NO, NO }, }, - {R"("\u20A43")", { { "\"₤3\"", Lexer::Type::string }, NO, NO, NO, NO }, }, - { "\"U+20AC4\"", { { "\"€4\"", Lexer::Type::string }, NO, NO, NO, NO }, }, + // String + { + "'one two'", + {{"'one two'", Lexer::Type::string}, NO, NO, NO, NO}, + }, + { + "\"three\"", + {{"\"three\"", Lexer::Type::string}, NO, NO, NO, NO}, + }, + { + "'\\''", + {{"'''", Lexer::Type::string}, NO, NO, NO, NO}, + }, + { + R"("\"")", + {{R"(""")", Lexer::Type::string}, NO, NO, NO, NO}, + }, + { + "\"\tfoo\t\"", + {{"\"\tfoo\t\"", Lexer::Type::string}, NO, NO, NO, NO}, + }, + { + R"("\u20A43")", + {{"\"₤3\"", Lexer::Type::string}, NO, NO, NO, NO}, + }, + { + "\"U+20AC4\"", + {{"\"€4\"", Lexer::Type::string}, NO, NO, NO, NO}, + }, - // Number - { "1", { { "1", Lexer::Type::number }, NO, NO, NO, NO }, }, - { "3.14", { { "3.14", Lexer::Type::number }, NO, NO, NO, NO }, }, - { "6.02217e23", { { "6.02217e23", Lexer::Type::number }, NO, NO, NO, NO }, }, - { "1.2e-3.4", { { "1.2e-3.4", Lexer::Type::number }, NO, NO, NO, NO }, }, - { "0x2f", { { "0x2f", Lexer::Type::hex }, NO, NO, NO, NO }, }, + // Number + { + "1", + {{"1", Lexer::Type::number}, NO, NO, NO, NO}, + }, + { + "3.14", + {{"3.14", Lexer::Type::number}, NO, NO, NO, NO}, + }, + { + "6.02217e23", + {{"6.02217e23", Lexer::Type::number}, NO, NO, NO, NO}, + }, + { + "1.2e-3.4", + {{"1.2e-3.4", Lexer::Type::number}, NO, NO, NO, NO}, + }, + { + "0x2f", + {{"0x2f", Lexer::Type::hex}, NO, NO, NO, NO}, + }, - // Set (1,2,4-7,9) - { "1,2", { { "1,2", Lexer::Type::set }, NO, NO, NO, NO }, }, - { "1-2", { { "1-2", Lexer::Type::set }, NO, NO, NO, NO }, }, - { "1-2,4", { { "1-2,4", Lexer::Type::set }, NO, NO, NO, NO }, }, - { "1-2,4,6-8", { { "1-2,4,6-8", Lexer::Type::set }, NO, NO, NO, NO }, }, - { "1-2,4,6-8,10-12", { { "1-2,4,6-8,10-12", Lexer::Type::set }, NO, NO, NO, NO }, }, + // Set (1,2,4-7,9) + { + "1,2", + {{"1,2", Lexer::Type::set}, NO, NO, NO, NO}, + }, + { + "1-2", + {{"1-2", Lexer::Type::set}, NO, NO, NO, NO}, + }, + { + "1-2,4", + {{"1-2,4", Lexer::Type::set}, NO, NO, NO, NO}, + }, + { + "1-2,4,6-8", + {{"1-2,4,6-8", Lexer::Type::set}, NO, NO, NO, NO}, + }, + { + "1-2,4,6-8,10-12", + {{"1-2,4,6-8,10-12", Lexer::Type::set}, NO, NO, NO, NO}, + }, - // Pair - { "name:value", { { "name:value", Lexer::Type::pair }, NO, NO, NO, NO }, }, - { "name=value", { { "name=value", Lexer::Type::pair }, NO, NO, NO, NO }, }, - { "name:=value", { { "name:=value", Lexer::Type::pair }, NO, NO, NO, NO }, }, - { "name.mod:value", { { "name.mod:value", Lexer::Type::pair }, NO, NO, NO, NO }, }, - { "name.mod=value", { { "name.mod=value", Lexer::Type::pair }, NO, NO, NO, NO }, }, - { "name:", { { "name:", Lexer::Type::pair }, NO, NO, NO, NO }, }, - { "name=", { { "name=", Lexer::Type::pair }, NO, NO, NO, NO }, }, - { "name.mod:", { { "name.mod:", Lexer::Type::pair }, NO, NO, NO, NO }, }, - { "name.mod=", { { "name.mod=", Lexer::Type::pair }, NO, NO, NO, NO }, }, - { "pro:'P 1'", { { "pro:'P 1'", Lexer::Type::pair }, NO, NO, NO, NO }, }, - { "rc:x", { { "rc:x", Lexer::Type::pair }, NO, NO, NO, NO }, }, - { "rc.name:value", { { "rc.name:value", Lexer::Type::pair }, NO, NO, NO, NO }, }, - { "rc.name=value", { { "rc.name=value", Lexer::Type::pair }, NO, NO, NO, NO }, }, - { "rc.name:=value", { { "rc.name:=value", Lexer::Type::pair }, NO, NO, NO, NO }, }, - { "due:='eow - 2d'", { { "due:='eow - 2d'", Lexer::Type::pair }, NO, NO, NO, NO }, }, - { "name:'foo\nbar'", { { "name:'foo\nbar'", Lexer::Type::pair }, NO, NO, NO, NO }, }, + // Pair + { + "name:value", + {{"name:value", Lexer::Type::pair}, NO, NO, NO, NO}, + }, + { + "name=value", + {{"name=value", Lexer::Type::pair}, NO, NO, NO, NO}, + }, + { + "name:=value", + {{"name:=value", Lexer::Type::pair}, NO, NO, NO, NO}, + }, + { + "name.mod:value", + {{"name.mod:value", Lexer::Type::pair}, NO, NO, NO, NO}, + }, + { + "name.mod=value", + {{"name.mod=value", Lexer::Type::pair}, NO, NO, NO, NO}, + }, + { + "name:", + {{"name:", Lexer::Type::pair}, NO, NO, NO, NO}, + }, + { + "name=", + {{"name=", Lexer::Type::pair}, NO, NO, NO, NO}, + }, + { + "name.mod:", + {{"name.mod:", Lexer::Type::pair}, NO, NO, NO, NO}, + }, + { + "name.mod=", + {{"name.mod=", Lexer::Type::pair}, NO, NO, NO, NO}, + }, + { + "pro:'P 1'", + {{"pro:'P 1'", Lexer::Type::pair}, NO, NO, NO, NO}, + }, + { + "rc:x", + {{"rc:x", Lexer::Type::pair}, NO, NO, NO, NO}, + }, + { + "rc.name:value", + {{"rc.name:value", Lexer::Type::pair}, NO, NO, NO, NO}, + }, + { + "rc.name=value", + {{"rc.name=value", Lexer::Type::pair}, NO, NO, NO, NO}, + }, + { + "rc.name:=value", + {{"rc.name:=value", Lexer::Type::pair}, NO, NO, NO, NO}, + }, + { + "due:='eow - 2d'", + {{"due:='eow - 2d'", Lexer::Type::pair}, NO, NO, NO, NO}, + }, + { + "name:'foo\nbar'", + {{"name:'foo\nbar'", Lexer::Type::pair}, NO, NO, NO, NO}, + }, - // Operator - complete set - { "^", { { "^", Lexer::Type::op }, NO, NO, NO, NO }, }, - { "!", { { "!", Lexer::Type::op }, NO, NO, NO, NO }, }, - { "_neg_", { { "_neg_", Lexer::Type::op }, NO, NO, NO, NO }, }, - { "_pos_", { { "_pos_", Lexer::Type::op }, NO, NO, NO, NO }, }, - { "_hastag_", { { "_hastag_", Lexer::Type::op }, NO, NO, NO, NO }, }, - { "_notag_", { { "_notag_", Lexer::Type::op }, NO, NO, NO, NO }, }, - { "*", { { "*", Lexer::Type::op }, NO, NO, NO, NO }, }, - { "/", { { "/", Lexer::Type::op }, NO, NO, NO, NO }, }, - { "%", { { "%", Lexer::Type::op }, NO, NO, NO, NO }, }, - { "+", { { "+", Lexer::Type::op }, NO, NO, NO, NO }, }, - { "-", { { "-", Lexer::Type::op }, NO, NO, NO, NO }, }, - { "<=", { { "<=", Lexer::Type::op }, NO, NO, NO, NO }, }, - { ">=", { { ">=", Lexer::Type::op }, NO, NO, NO, NO }, }, - { ">", { { ">", Lexer::Type::op }, NO, NO, NO, NO }, }, - { "<", { { "<", Lexer::Type::op }, NO, NO, NO, NO }, }, - { "=", { { "=", Lexer::Type::op }, NO, NO, NO, NO }, }, - { "==", { { "==", Lexer::Type::op }, NO, NO, NO, NO }, }, - { "!=", { { "!=", Lexer::Type::op }, NO, NO, NO, NO }, }, - { "!==", { { "!==", Lexer::Type::op }, NO, NO, NO, NO }, }, - { "~", { { "~", Lexer::Type::op }, NO, NO, NO, NO }, }, - { "!~", { { "!~", Lexer::Type::op }, NO, NO, NO, NO }, }, - { "and", { { "and", Lexer::Type::op }, NO, NO, NO, NO }, }, - { "or", { { "or", Lexer::Type::op }, NO, NO, NO, NO }, }, - { "xor", { { "xor", Lexer::Type::op }, NO, NO, NO, NO }, }, - { "(", { { "(", Lexer::Type::op }, NO, NO, NO, NO }, }, - { ")", { { ")", Lexer::Type::op }, NO, NO, NO, NO }, }, + // Operator - complete set + { + "^", + {{"^", Lexer::Type::op}, NO, NO, NO, NO}, + }, + { + "!", + {{"!", Lexer::Type::op}, NO, NO, NO, NO}, + }, + { + "_neg_", + {{"_neg_", Lexer::Type::op}, NO, NO, NO, NO}, + }, + { + "_pos_", + {{"_pos_", Lexer::Type::op}, NO, NO, NO, NO}, + }, + { + "_hastag_", + {{"_hastag_", Lexer::Type::op}, NO, NO, NO, NO}, + }, + { + "_notag_", + {{"_notag_", Lexer::Type::op}, NO, NO, NO, NO}, + }, + { + "*", + {{"*", Lexer::Type::op}, NO, NO, NO, NO}, + }, + { + "/", + {{"/", Lexer::Type::op}, NO, NO, NO, NO}, + }, + { + "%", + {{"%", Lexer::Type::op}, NO, NO, NO, NO}, + }, + { + "+", + {{"+", Lexer::Type::op}, NO, NO, NO, NO}, + }, + { + "-", + {{"-", Lexer::Type::op}, NO, NO, NO, NO}, + }, + { + "<=", + {{"<=", Lexer::Type::op}, NO, NO, NO, NO}, + }, + { + ">=", + {{">=", Lexer::Type::op}, NO, NO, NO, NO}, + }, + { + ">", + {{">", Lexer::Type::op}, NO, NO, NO, NO}, + }, + { + "<", + {{"<", Lexer::Type::op}, NO, NO, NO, NO}, + }, + { + "=", + {{"=", Lexer::Type::op}, NO, NO, NO, NO}, + }, + { + "==", + {{"==", Lexer::Type::op}, NO, NO, NO, NO}, + }, + { + "!=", + {{"!=", Lexer::Type::op}, NO, NO, NO, NO}, + }, + { + "!==", + {{"!==", Lexer::Type::op}, NO, NO, NO, NO}, + }, + { + "~", + {{"~", Lexer::Type::op}, NO, NO, NO, NO}, + }, + { + "!~", + {{"!~", Lexer::Type::op}, NO, NO, NO, NO}, + }, + { + "and", + {{"and", Lexer::Type::op}, NO, NO, NO, NO}, + }, + { + "or", + {{"or", Lexer::Type::op}, NO, NO, NO, NO}, + }, + { + "xor", + {{"xor", Lexer::Type::op}, NO, NO, NO, NO}, + }, + { + "(", + {{"(", Lexer::Type::op}, NO, NO, NO, NO}, + }, + { + ")", + {{")", Lexer::Type::op}, NO, NO, NO, NO}, + }, - // UUID - { "ffffffff-ffff-ffff-ffff-ffffffffffff", { { "ffffffff-ffff-ffff-ffff-ffffffffffff", Lexer::Type::uuid }, NO, NO, NO, NO }, }, - { "0000000d-0000-0000-0000-000000000000", { { "0000000d-0000-0000-0000-000000000000", Lexer::Type::uuid, true, true }, NO, NO, NO, NO }, }, - { "00000000-0000-0000-0000-0000000", { { "00000000-0000-0000-0000-0000000", Lexer::Type::uuid }, NO, NO, NO, NO }, }, - { "00000000-0000-0000-0000", { { "00000000-0000-0000-0000", Lexer::Type::uuid }, NO, NO, NO, NO }, }, - { "00000000-0000-0000", { { "00000000-0000-0000", Lexer::Type::uuid }, NO, NO, NO, NO }, }, - { "00000000-0000", { { "00000000-0000", Lexer::Type::uuid }, NO, NO, NO, NO }, }, - { "00000000", { { "00000000", Lexer::Type::uuid }, NO, NO, NO, NO }, }, - { "a360fc44-315c-4366-b70c-ea7e7520b749", { { "a360fc44-315c-4366-b70c-ea7e7520b749", Lexer::Type::uuid }, NO, NO, NO, NO }, }, - { "a360fc44-315c-4366-b70c-ea7e752", { { "a360fc44-315c-4366-b70c-ea7e752", Lexer::Type::uuid }, NO, NO, NO, NO }, }, - { "a360fc44-315c-4366-b70c", { { "a360fc44-315c-4366-b70c", Lexer::Type::uuid }, NO, NO, NO, NO }, }, - { "a360fc44-315c-4366", { { "a360fc44-315c-4366", Lexer::Type::uuid }, NO, NO, NO, NO }, }, - { "a360fc44-315c", { { "a360fc44-315c", Lexer::Type::uuid }, NO, NO, NO, NO }, }, - { "a360fc44", { { "a360fc44", Lexer::Type::uuid }, NO, NO, NO, NO }, }, + // UUID + { + "ffffffff-ffff-ffff-ffff-ffffffffffff", + {{"ffffffff-ffff-ffff-ffff-ffffffffffff", Lexer::Type::uuid}, NO, NO, NO, NO}, + }, + { + "0000000d-0000-0000-0000-000000000000", + {{"0000000d-0000-0000-0000-000000000000", Lexer::Type::uuid, true, true}, NO, NO, NO, NO}, + }, + { + "00000000-0000-0000-0000-0000000", + {{"00000000-0000-0000-0000-0000000", Lexer::Type::uuid}, NO, NO, NO, NO}, + }, + { + "00000000-0000-0000-0000", + {{"00000000-0000-0000-0000", Lexer::Type::uuid}, NO, NO, NO, NO}, + }, + { + "00000000-0000-0000", + {{"00000000-0000-0000", Lexer::Type::uuid}, NO, NO, NO, NO}, + }, + { + "00000000-0000", + {{"00000000-0000", Lexer::Type::uuid}, NO, NO, NO, NO}, + }, + { + "00000000", + {{"00000000", Lexer::Type::uuid}, NO, NO, NO, NO}, + }, + { + "a360fc44-315c-4366-b70c-ea7e7520b749", + {{"a360fc44-315c-4366-b70c-ea7e7520b749", Lexer::Type::uuid}, NO, NO, NO, NO}, + }, + { + "a360fc44-315c-4366-b70c-ea7e752", + {{"a360fc44-315c-4366-b70c-ea7e752", Lexer::Type::uuid}, NO, NO, NO, NO}, + }, + { + "a360fc44-315c-4366-b70c", + {{"a360fc44-315c-4366-b70c", Lexer::Type::uuid}, NO, NO, NO, NO}, + }, + { + "a360fc44-315c-4366", + {{"a360fc44-315c-4366", Lexer::Type::uuid}, NO, NO, NO, NO}, + }, + { + "a360fc44-315c", + {{"a360fc44-315c", Lexer::Type::uuid}, NO, NO, NO, NO}, + }, + { + "a360fc44", + {{"a360fc44", Lexer::Type::uuid}, NO, NO, NO, NO}, + }, - // Date - { "2015-W01", { { "2015-W01", Lexer::Type::date }, NO, NO, NO, NO }, }, - { "2015-02-17", { { "2015-02-17", Lexer::Type::date }, NO, NO, NO, NO }, }, - { "2013-11-29T22:58:00Z", { { "2013-11-29T22:58:00Z", Lexer::Type::date }, NO, NO, NO, NO }, }, - { "20131129T225800Z", { { "20131129T225800Z", Lexer::Type::date }, NO, NO, NO, NO }, }, + // Date + { + "2015-W01", + {{"2015-W01", Lexer::Type::date}, NO, NO, NO, NO}, + }, + { + "2015-02-17", + {{"2015-02-17", Lexer::Type::date}, NO, NO, NO, NO}, + }, + { + "2013-11-29T22:58:00Z", + {{"2013-11-29T22:58:00Z", Lexer::Type::date}, NO, NO, NO, NO}, + }, + { + "20131129T225800Z", + {{"20131129T225800Z", Lexer::Type::date}, NO, NO, NO, NO}, + }, #ifdef PRODUCT_TASKWARRIOR - { "9th", { { "9th", Lexer::Type::date }, NO, NO, NO, NO }, }, - { "10th", { { "10th", Lexer::Type::date }, NO, NO, NO, NO }, }, - { "today", { { "today", Lexer::Type::date }, NO, NO, NO, NO }, }, + { + "9th", + {{"9th", Lexer::Type::date}, NO, NO, NO, NO}, + }, + { + "10th", + {{"10th", Lexer::Type::date}, NO, NO, NO, NO}, + }, + { + "today", + {{"today", Lexer::Type::date}, NO, NO, NO, NO}, + }, #endif - // Duration - { "year", { { "year", Lexer::Type::duration }, NO, NO, NO, NO }, }, - { "4weeks", { { "4weeks", Lexer::Type::duration }, NO, NO, NO, NO }, }, - { "PT23H", { { "PT23H", Lexer::Type::duration }, NO, NO, NO, NO }, }, - { "1second", { { "1second", Lexer::Type::duration }, NO, NO, NO, NO }, }, - { "1s", { { "1s", Lexer::Type::duration }, NO, NO, NO, NO }, }, - { "1minute", { { "1minute", Lexer::Type::duration }, NO, NO, NO, NO }, }, - { "2hour", { { "2hour", Lexer::Type::duration }, NO, NO, NO, NO }, }, - { "3 days", { { "3 days", Lexer::Type::duration }, NO, NO, NO, NO }, }, - { "4w", { { "4w", Lexer::Type::duration }, NO, NO, NO, NO }, }, - { "5mo", { { "5mo", Lexer::Type::duration }, NO, NO, NO, NO }, }, - { "6 years", { { "6 years", Lexer::Type::duration }, NO, NO, NO, NO }, }, - { "P1Y", { { "P1Y", Lexer::Type::duration }, NO, NO, NO, NO }, }, - { "PT1H", { { "PT1H", Lexer::Type::duration }, NO, NO, NO, NO }, }, - { "P1Y1M1DT1H1M1S", { { "P1Y1M1DT1H1M1S", Lexer::Type::duration }, NO, NO, NO, NO }, }, + // Duration + { + "year", + {{"year", Lexer::Type::duration}, NO, NO, NO, NO}, + }, + { + "4weeks", + {{"4weeks", Lexer::Type::duration}, NO, NO, NO, NO}, + }, + { + "PT23H", + {{"PT23H", Lexer::Type::duration}, NO, NO, NO, NO}, + }, + { + "1second", + {{"1second", Lexer::Type::duration}, NO, NO, NO, NO}, + }, + { + "1s", + {{"1s", Lexer::Type::duration}, NO, NO, NO, NO}, + }, + { + "1minute", + {{"1minute", Lexer::Type::duration}, NO, NO, NO, NO}, + }, + { + "2hour", + {{"2hour", Lexer::Type::duration}, NO, NO, NO, NO}, + }, + { + "3 days", + {{"3 days", Lexer::Type::duration}, NO, NO, NO, NO}, + }, + { + "4w", + {{"4w", Lexer::Type::duration}, NO, NO, NO, NO}, + }, + { + "5mo", + {{"5mo", Lexer::Type::duration}, NO, NO, NO, NO}, + }, + { + "6 years", + {{"6 years", Lexer::Type::duration}, NO, NO, NO, NO}, + }, + { + "P1Y", + {{"P1Y", Lexer::Type::duration}, NO, NO, NO, NO}, + }, + { + "PT1H", + {{"PT1H", Lexer::Type::duration}, NO, NO, NO, NO}, + }, + { + "P1Y1M1DT1H1M1S", + {{"P1Y1M1DT1H1M1S", Lexer::Type::duration}, NO, NO, NO, NO}, + }, - // Misc - { "--", { { "--", Lexer::Type::separator }, NO, NO, NO, NO }, }, + // Misc + { + "--", + {{"--", Lexer::Type::separator}, NO, NO, NO, NO}, + }, - // Expression - // due:eom-2w - // due < eom + 1w + 1d - // ( /pattern/ or 8ad2e3db-914d-4832-b0e6-72fa04f6e331,3b6218f9-726a-44fc-aa63-889ff52be442 ) - { "(1+2)", { { "(", Lexer::Type::op }, - { "1", Lexer::Type::number }, - { "+", Lexer::Type::op }, - { "2", Lexer::Type::number }, - { ")", Lexer::Type::op }, }, }, - { "description~pattern", { { "description", Lexer::Type::dom }, - { "~", Lexer::Type::op }, - { "pattern", Lexer::Type::identifier }, NO, NO }, }, - { "(+tag)", { { "(", Lexer::Type::op }, - { "+tag", Lexer::Type::tag }, - { ")", Lexer::Type::op }, NO, NO }, }, - { "(name:value)", { { "(", Lexer::Type::op }, - { "name:value", Lexer::Type::pair }, - { ")", Lexer::Type::op }, NO, NO }, }, + // Expression + // due:eom-2w + // due < eom + 1w + 1d + // ( /pattern/ or 8ad2e3db-914d-4832-b0e6-72fa04f6e331,3b6218f9-726a-44fc-aa63-889ff52be442 + // ) + { + "(1+2)", + { + {"(", Lexer::Type::op}, + {"1", Lexer::Type::number}, + {"+", Lexer::Type::op}, + {"2", Lexer::Type::number}, + {")", Lexer::Type::op}, + }, + }, + { + "description~pattern", + {{"description", Lexer::Type::dom}, + {"~", Lexer::Type::op}, + {"pattern", Lexer::Type::identifier}, + NO, + NO}, + }, + { + "(+tag)", + {{"(", Lexer::Type::op}, {"+tag", Lexer::Type::tag}, {")", Lexer::Type::op}, NO, NO}, + }, + { + "(name:value)", + {{"(", Lexer::Type::op}, + {"name:value", Lexer::Type::pair}, + {")", Lexer::Type::op}, + NO, + NO}, + }, }; - for (const auto& lexerTest : lexerTests) - { + for (const auto& lexerTest : lexerTests) { // The isolated test puts the input string directly into the Lexer. - Lexer isolated (lexerTest.input); + Lexer isolated(lexerTest.input); - for (const auto& result : lexerTest.results) - { - if (result.token[0]) - { + for (const auto& result : lexerTest.results) { + if (result.token[0]) { // Isolated: "" - t.ok (isolated.token (token, type), "Isolated Lexer::token(...) --> true"); - t.is (token, result.token, " token --> " + token, result.expfail_token); - t.is ((int)type, (int)result.type, " type --> Lexer::Type::" + Lexer::typeToString (type), result.expfail_type); + t.ok(isolated.token(token, type), "Isolated Lexer::token(...) --> true"); + t.is(token, result.token, " token --> " + token, result.expfail_token); + t.is((int)type, (int)result.type, " type --> Lexer::Type::" + Lexer::typeToString(type), + result.expfail_type); } } // The embedded test surrounds the input string with a space. - Lexer embedded (std::string (" ") + lexerTest.input + " "); + Lexer embedded(std::string(" ") + lexerTest.input + " "); - for (const auto& result : lexerTest.results) - { - if (result.token[0]) - { + for (const auto& result : lexerTest.results) { + if (result.token[0]) { // Embedded: "" - t.ok (embedded.token (token, type), "Embedded Lexer::token(...) --> true"); - t.is (token, result.token, " token --> " + token, result.expfail_token); - t.is ((int)type, (int)result.type, " type --> Lexer::Type::" + Lexer::typeToString (type), result.expfail_type); + t.ok(embedded.token(token, type), "Embedded Lexer::token(...) --> true"); + t.is(token, result.token, " token --> " + token, result.expfail_token); + t.is((int)type, (int)result.type, " type --> Lexer::Type::" + Lexer::typeToString(type), + result.expfail_type); } } } - t.is (Lexer::typeName (Lexer::Type::uuid), "uuid", "Lexer::typeName (Lexer::Type::uuid)"); - t.is (Lexer::typeName (Lexer::Type::number), "number", "Lexer::typeName (Lexer::Type::number)"); - t.is (Lexer::typeName (Lexer::Type::hex), "hex", "Lexer::typeName (Lexer::Type::hex)"); - t.is (Lexer::typeName (Lexer::Type::string), "string", "Lexer::typeName (Lexer::Type::string)"); - t.is (Lexer::typeName (Lexer::Type::url), "url", "Lexer::typeName (Lexer::Type::url)"); - t.is (Lexer::typeName (Lexer::Type::pair), "pair", "Lexer::typeName (Lexer::Type::pair)"); - t.is (Lexer::typeName (Lexer::Type::set), "set", "Lexer::typeName (Lexer::Type::set)"); - t.is (Lexer::typeName (Lexer::Type::separator), "separator", "Lexer::typeName (Lexer::Type::separator)"); - t.is (Lexer::typeName (Lexer::Type::tag), "tag", "Lexer::typeName (Lexer::Type::tag)"); - t.is (Lexer::typeName (Lexer::Type::path), "path", "Lexer::typeName (Lexer::Type::path)"); - t.is (Lexer::typeName (Lexer::Type::substitution), "substitution", "Lexer::typeName (Lexer::Type::substitution)"); - t.is (Lexer::typeName (Lexer::Type::pattern), "pattern", "Lexer::typeName (Lexer::Type::pattern)"); - t.is (Lexer::typeName (Lexer::Type::op), "op", "Lexer::typeName (Lexer::Type::op)"); - t.is (Lexer::typeName (Lexer::Type::dom), "dom", "Lexer::typeName (Lexer::Type::dom)"); - t.is (Lexer::typeName (Lexer::Type::identifier), "identifier", "Lexer::typeName (Lexer::Type::identifier)"); - t.is (Lexer::typeName (Lexer::Type::word), "word", "Lexer::typeName (Lexer::Type::word)"); - t.is (Lexer::typeName (Lexer::Type::date), "date", "Lexer::typeName (Lexer::Type::date)"); - t.is (Lexer::typeName (Lexer::Type::duration), "duration", "Lexer::typeName (Lexer::Type::duration)"); + t.is(Lexer::typeName(Lexer::Type::uuid), "uuid", "Lexer::typeName (Lexer::Type::uuid)"); + t.is(Lexer::typeName(Lexer::Type::number), "number", "Lexer::typeName (Lexer::Type::number)"); + t.is(Lexer::typeName(Lexer::Type::hex), "hex", "Lexer::typeName (Lexer::Type::hex)"); + t.is(Lexer::typeName(Lexer::Type::string), "string", "Lexer::typeName (Lexer::Type::string)"); + t.is(Lexer::typeName(Lexer::Type::url), "url", "Lexer::typeName (Lexer::Type::url)"); + t.is(Lexer::typeName(Lexer::Type::pair), "pair", "Lexer::typeName (Lexer::Type::pair)"); + t.is(Lexer::typeName(Lexer::Type::set), "set", "Lexer::typeName (Lexer::Type::set)"); + t.is(Lexer::typeName(Lexer::Type::separator), "separator", + "Lexer::typeName (Lexer::Type::separator)"); + t.is(Lexer::typeName(Lexer::Type::tag), "tag", "Lexer::typeName (Lexer::Type::tag)"); + t.is(Lexer::typeName(Lexer::Type::path), "path", "Lexer::typeName (Lexer::Type::path)"); + t.is(Lexer::typeName(Lexer::Type::substitution), "substitution", + "Lexer::typeName (Lexer::Type::substitution)"); + t.is(Lexer::typeName(Lexer::Type::pattern), "pattern", "Lexer::typeName (Lexer::Type::pattern)"); + t.is(Lexer::typeName(Lexer::Type::op), "op", "Lexer::typeName (Lexer::Type::op)"); + t.is(Lexer::typeName(Lexer::Type::dom), "dom", "Lexer::typeName (Lexer::Type::dom)"); + t.is(Lexer::typeName(Lexer::Type::identifier), "identifier", + "Lexer::typeName (Lexer::Type::identifier)"); + t.is(Lexer::typeName(Lexer::Type::word), "word", "Lexer::typeName (Lexer::Type::word)"); + t.is(Lexer::typeName(Lexer::Type::date), "date", "Lexer::typeName (Lexer::Type::date)"); + t.is(Lexer::typeName(Lexer::Type::duration), "duration", + "Lexer::typeName (Lexer::Type::duration)"); // std::string Lexer::lowerCase (const std::string& input) - t.is (Lexer::lowerCase (""), "", "Lexer::lowerCase '' -> ''"); - t.is (Lexer::lowerCase ("pre01_:POST"), "pre01_:post", "Lexer::lowerCase 'pre01_:POST' -> 'pre01_:post'"); + t.is(Lexer::lowerCase(""), "", "Lexer::lowerCase '' -> ''"); + t.is(Lexer::lowerCase("pre01_:POST"), "pre01_:post", + "Lexer::lowerCase 'pre01_:POST' -> 'pre01_:post'"); // std::string Lexer::commify (const std::string& data) - t.is (Lexer::commify (""), "", "Lexer::commify '' -> ''"); - t.is (Lexer::commify ("1"), "1", "Lexer::commify '1' -> '1'"); - t.is (Lexer::commify ("12"), "12", "Lexer::commify '12' -> '12'"); - t.is (Lexer::commify ("123"), "123", "Lexer::commify '123' -> '123'"); - t.is (Lexer::commify ("1234"), "1,234", "Lexer::commify '1234' -> '1,234'"); - t.is (Lexer::commify ("12345"), "12,345", "Lexer::commify '12345' -> '12,345'"); - t.is (Lexer::commify ("123456"), "123,456", "Lexer::commify '123456' -> '123,456'"); - t.is (Lexer::commify ("1234567"), "1,234,567", "Lexer::commify '1234567' -> '1,234,567'"); - t.is (Lexer::commify ("12345678"), "12,345,678", "Lexer::commify '12345678' -> '12,345,678'"); - t.is (Lexer::commify ("123456789"), "123,456,789", "Lexer::commify '123456789' -> '123,456,789'"); - t.is (Lexer::commify ("1234567890"), "1,234,567,890", "Lexer::commify '1234567890' -> '1,234,567,890'"); - t.is (Lexer::commify ("1.0"), "1.0", "Lexer::commify '1.0' -> '1.0'"); - t.is (Lexer::commify ("12.0"), "12.0", "Lexer::commify '12.0' -> '12.0'"); - t.is (Lexer::commify ("123.0"), "123.0", "Lexer::commify '123.0' -> '123.0'"); - t.is (Lexer::commify ("1234.0"), "1,234.0", "Lexer::commify '1234.0' -> '1,234.0'"); - t.is (Lexer::commify ("12345.0"), "12,345.0", "Lexer::commify '12345.0' -> '12,345.0'"); - t.is (Lexer::commify ("123456.0"), "123,456.0", "Lexer::commify '123456.0' -> '123,456.0'"); - t.is (Lexer::commify ("1234567.0"), "1,234,567.0", "Lexer::commify '1234567.0' -> '1,234,567.0'"); - t.is (Lexer::commify ("12345678.0"), "12,345,678.0", "Lexer::commify '12345678.0' -> '12,345,678.0'"); - t.is (Lexer::commify ("123456789.0"), "123,456,789.0", "Lexer::commify '123456789.0' -> '123,456,789.0'"); - t.is (Lexer::commify ("1234567890.0"), "1,234,567,890.0", "Lexer::commify '1234567890.0' -> '1,234,567,890.0'"); - t.is (Lexer::commify ("pre"), "pre", "Lexer::commify 'pre' -> 'pre'"); - t.is (Lexer::commify ("pre1234"), "pre1,234", "Lexer::commify 'pre1234' -> 'pre1,234'"); - t.is (Lexer::commify ("1234post"), "1,234post", "Lexer::commify '1234post' -> '1,234post'"); - t.is (Lexer::commify ("pre1234post"), "pre1,234post", "Lexer::commify 'pre1234post' -> 'pre1,234post'"); + t.is(Lexer::commify(""), "", "Lexer::commify '' -> ''"); + t.is(Lexer::commify("1"), "1", "Lexer::commify '1' -> '1'"); + t.is(Lexer::commify("12"), "12", "Lexer::commify '12' -> '12'"); + t.is(Lexer::commify("123"), "123", "Lexer::commify '123' -> '123'"); + t.is(Lexer::commify("1234"), "1,234", "Lexer::commify '1234' -> '1,234'"); + t.is(Lexer::commify("12345"), "12,345", "Lexer::commify '12345' -> '12,345'"); + t.is(Lexer::commify("123456"), "123,456", "Lexer::commify '123456' -> '123,456'"); + t.is(Lexer::commify("1234567"), "1,234,567", "Lexer::commify '1234567' -> '1,234,567'"); + t.is(Lexer::commify("12345678"), "12,345,678", "Lexer::commify '12345678' -> '12,345,678'"); + t.is(Lexer::commify("123456789"), "123,456,789", "Lexer::commify '123456789' -> '123,456,789'"); + t.is(Lexer::commify("1234567890"), "1,234,567,890", + "Lexer::commify '1234567890' -> '1,234,567,890'"); + t.is(Lexer::commify("1.0"), "1.0", "Lexer::commify '1.0' -> '1.0'"); + t.is(Lexer::commify("12.0"), "12.0", "Lexer::commify '12.0' -> '12.0'"); + t.is(Lexer::commify("123.0"), "123.0", "Lexer::commify '123.0' -> '123.0'"); + t.is(Lexer::commify("1234.0"), "1,234.0", "Lexer::commify '1234.0' -> '1,234.0'"); + t.is(Lexer::commify("12345.0"), "12,345.0", "Lexer::commify '12345.0' -> '12,345.0'"); + t.is(Lexer::commify("123456.0"), "123,456.0", "Lexer::commify '123456.0' -> '123,456.0'"); + t.is(Lexer::commify("1234567.0"), "1,234,567.0", "Lexer::commify '1234567.0' -> '1,234,567.0'"); + t.is(Lexer::commify("12345678.0"), "12,345,678.0", + "Lexer::commify '12345678.0' -> '12,345,678.0'"); + t.is(Lexer::commify("123456789.0"), "123,456,789.0", + "Lexer::commify '123456789.0' -> '123,456,789.0'"); + t.is(Lexer::commify("1234567890.0"), "1,234,567,890.0", + "Lexer::commify '1234567890.0' -> '1,234,567,890.0'"); + t.is(Lexer::commify("pre"), "pre", "Lexer::commify 'pre' -> 'pre'"); + t.is(Lexer::commify("pre1234"), "pre1,234", "Lexer::commify 'pre1234' -> 'pre1,234'"); + t.is(Lexer::commify("1234post"), "1,234post", "Lexer::commify '1234post' -> '1,234post'"); + t.is(Lexer::commify("pre1234post"), "pre1,234post", + "Lexer::commify 'pre1234post' -> 'pre1,234post'"); // std::string Lexer::trimLeft (const std::string& in, const std::string& t /*= " "*/) - t.is (Lexer::trimLeft (""), "", "Lexer::trimLeft '' -> ''"); - t.is (Lexer::trimLeft (" "), "", "Lexer::trimLeft ' ' -> ''"); - t.is (Lexer::trimLeft ("", " \t"), "", "Lexer::trimLeft '' -> ''"); - t.is (Lexer::trimLeft ("xxx"), "xxx", "Lexer::trimLeft 'xxx' -> 'xxx'"); - t.is (Lexer::trimLeft ("xxx", " \t"), "xxx", "Lexer::trimLeft 'xxx' -> 'xxx'"); - t.is (Lexer::trimLeft (" \t xxx \t "), "\t xxx \t ",R"(Lexer::trimLeft ' \t xxx \t ' -> '\t xxx \t ')"); - t.is (Lexer::trimLeft (" \t xxx \t ", " \t"), "xxx \t ", R"(Lexer::trimLeft ' \t xxx \t ' -> 'xxx \t ')"); + t.is(Lexer::trimLeft(""), "", "Lexer::trimLeft '' -> ''"); + t.is(Lexer::trimLeft(" "), "", "Lexer::trimLeft ' ' -> ''"); + t.is(Lexer::trimLeft("", " \t"), "", "Lexer::trimLeft '' -> ''"); + t.is(Lexer::trimLeft("xxx"), "xxx", "Lexer::trimLeft 'xxx' -> 'xxx'"); + t.is(Lexer::trimLeft("xxx", " \t"), "xxx", "Lexer::trimLeft 'xxx' -> 'xxx'"); + t.is(Lexer::trimLeft(" \t xxx \t "), "\t xxx \t ", + R"(Lexer::trimLeft ' \t xxx \t ' -> '\t xxx \t ')"); + t.is(Lexer::trimLeft(" \t xxx \t ", " \t"), "xxx \t ", + R"(Lexer::trimLeft ' \t xxx \t ' -> 'xxx \t ')"); // std::string Lexer::trimRight (const std::string& in, const std::string& t /*= " "*/) - t.is (Lexer::trimRight (""), "", "Lexer::trimRight '' -> ''"); - t.is (Lexer::trimRight (" "), "", "Lexer::trimRight ' ' -> ''"); - t.is (Lexer::trimRight ("", " \t"), "", "Lexer::trimRight '' -> ''"); - t.is (Lexer::trimRight ("xxx"), "xxx", "Lexer::trimRight 'xxx' -> 'xxx'"); - t.is (Lexer::trimRight ("xxx", " \t"), "xxx", "Lexer::trimRight 'xxx' -> 'xxx'"); - t.is (Lexer::trimRight (" \t xxx \t "), " \t xxx \t", R"(Lexer::trimRight ' \t xxx \t ' -> ' \t xxx \t')"); - t.is (Lexer::trimRight (" \t xxx \t ", " \t"), " \t xxx", R"(Lexer::trimRight ' \t xxx \t ' -> ' \t xxx')"); + t.is(Lexer::trimRight(""), "", "Lexer::trimRight '' -> ''"); + t.is(Lexer::trimRight(" "), "", "Lexer::trimRight ' ' -> ''"); + t.is(Lexer::trimRight("", " \t"), "", "Lexer::trimRight '' -> ''"); + t.is(Lexer::trimRight("xxx"), "xxx", "Lexer::trimRight 'xxx' -> 'xxx'"); + t.is(Lexer::trimRight("xxx", " \t"), "xxx", "Lexer::trimRight 'xxx' -> 'xxx'"); + t.is(Lexer::trimRight(" \t xxx \t "), " \t xxx \t", + R"(Lexer::trimRight ' \t xxx \t ' -> ' \t xxx \t')"); + t.is(Lexer::trimRight(" \t xxx \t ", " \t"), " \t xxx", + R"(Lexer::trimRight ' \t xxx \t ' -> ' \t xxx')"); // std::string Lexer::trim (const std::string& in, const std::string& t /*= " "*/) - t.is (Lexer::trim (""), "", "Lexer::trim '' -> ''"); - t.is (Lexer::trim (" "), "", "Lexer::trim ' ' -> ''"); - t.is (Lexer::trim ("", " \t"), "", "Lexer::trim '' -> ''"); - t.is (Lexer::trim ("xxx"), "xxx", "Lexer::trim 'xxx' -> 'xxx'"); - t.is (Lexer::trim ("xxx", " \t"), "xxx", "Lexer::trim 'xxx' -> 'xxx'"); - t.is (Lexer::trim (" \t xxx \t "), "\t xxx \t",R"(Lexer::trim ' \t xxx \t ' -> '\t xxx \t')"); - t.is (Lexer::trim (" \t xxx \t ", " \t"), "xxx", "Lexer::trim ' \\t xxx \\t ' -> 'xxx'"); + t.is(Lexer::trim(""), "", "Lexer::trim '' -> ''"); + t.is(Lexer::trim(" "), "", "Lexer::trim ' ' -> ''"); + t.is(Lexer::trim("", " \t"), "", "Lexer::trim '' -> ''"); + t.is(Lexer::trim("xxx"), "xxx", "Lexer::trim 'xxx' -> 'xxx'"); + t.is(Lexer::trim("xxx", " \t"), "xxx", "Lexer::trim 'xxx' -> 'xxx'"); + t.is(Lexer::trim(" \t xxx \t "), "\t xxx \t", R"(Lexer::trim ' \t xxx \t ' -> '\t xxx \t')"); + t.is(Lexer::trim(" \t xxx \t ", " \t"), "xxx", "Lexer::trim ' \\t xxx \\t ' -> 'xxx'"); return 0; } diff --git a/test/limit.test.py b/test/limit.test.py index 79baa0af0..63e505f7c 100755 --- a/test/limit.test.py +++ b/test/limit.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -101,6 +102,7 @@ class TestLimit(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/list.all.projects.test.py b/test/list.all.projects.test.py index 380118862..a9248646d 100755 --- a/test/list.all.projects.test.py +++ b/test/list.all.projects.test.py @@ -28,11 +28,13 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) from basetest import Task, TestCase + class TestListAllProjects(TestCase): @classmethod def setUpClass(cls): @@ -56,6 +58,7 @@ class TestListAllProjects(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/log.test.py b/test/log.test.py index 2a145023a..946a74a02 100755 --- a/test/log.test.py +++ b/test/log.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -64,7 +65,7 @@ class TestBug1575(TestCase): def test_spurious_whitespace_in_url(self): """1575: ensure that extra whitespace does not get inserted into a URL. - tw-1575: `task log` mangles URLs when quoted + tw-1575: `task log` mangles URLs when quoted """ self.t("log testing123 https://foo.example.com") @@ -74,6 +75,7 @@ class TestBug1575(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/logo.test.py b/test/logo.test.py index 1cc80aa35..9467d8e56 100755 --- a/test/logo.test.py +++ b/test/logo.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -52,6 +53,7 @@ class TestLogoCommand(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/math.test.py b/test/math.test.py index 62c05d41d..13d97562d 100755 --- a/test/math.test.py +++ b/test/math.test.py @@ -29,6 +29,7 @@ import sys import os import unittest from datetime import datetime + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -51,64 +52,66 @@ class TestMath(TestCase): cls.t("add three 'due:eoy-10days'") cls.t("add four due:'eoy - 10days'") cls.t("add five 'due:eoy - 10days'") - cls.t("add six 'due:{}-12-31T23:59:59 - 10days'".format (datetime.now().year)) + cls.t("add six 'due:{}-12-31T23:59:59 - 10days'".format(datetime.now().year)) def test_compact_unquoted(self): """compact unquoted""" - code, out, err = self.t('_get 1.due') + code, out, err = self.t("_get 1.due") self.assertEqual(out, self.when) def test_compact_value_quoted(self): """compact value quoted""" - code, out, err = self.t('_get 2.due') + code, out, err = self.t("_get 2.due") self.assertEqual(out, self.when) def test_compact_arg_quoted(self): """compact arg quoted""" - code, out, err = self.t('_get 3.due') + code, out, err = self.t("_get 3.due") self.assertEqual(out, self.when) def test_sparse_value_quoted(self): """sparse value quoted""" - code, out, err = self.t('_get 4.due') + code, out, err = self.t("_get 4.due") self.assertEqual(out, self.when) def test_sparse_arg_quoted(self): """sparse arg quoted""" - code, out, err = self.t('_get 5.due') + code, out, err = self.t("_get 5.due") self.assertEqual(out, self.when) def test_sparse_arg_quoted_literal(self): """sparse arg quoted literal""" - code, out, err = self.t('_get 6.due') + code, out, err = self.t("_get 6.due") self.assertEqual(out, self.when) + class TestBug851(TestCase): @classmethod def setUpClass(cls): """Executed once before any test in the class""" cls.t = Task() - cls.t('add past due:-2days') - cls.t('add future due:2days') + cls.t("add past due:-2days") + cls.t("add future due:2days") def setUp(self): """Executed before each test in the class""" def test_attribute_before_with_math(self): """851: Test due.before:now+1d""" - code, out, err = self.t('due.before:now+1day ls') + code, out, err = self.t("due.before:now+1day ls") self.assertIn("past", out) self.assertNotIn("future", out) def test_attribute_after_with_math(self): """851: Test due.after:now+1d""" - code, out, err = self.t('due.after:now+1day ls') + code, out, err = self.t("due.after:now+1day ls") self.assertNotIn("past", out) self.assertIn("future", out) if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/modify.test.py b/test/modify.test.py index f61bfdad9..2a992e530 100755 --- a/test/modify.test.py +++ b/test/modify.test.py @@ -28,10 +28,12 @@ import sys import os import unittest + sys.path.append(os.path.dirname(os.path.abspath(__file__))) from basetest import Task, TestCase + class TestBug1306(TestCase): def setUp(self): self.t = Task() @@ -42,6 +44,7 @@ class TestBug1306(TestCase): code, out, err = self.t("1 info") self.assertIn("PROJ", out) + class TestBug1763(TestCase): def setUp(self): self.t = Task() @@ -52,8 +55,10 @@ class TestBug1763(TestCase): code, out, err = self.t("1 modify due:") self.assertIn("Modified 0 tasks.", out) + if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/nag.test.py b/test/nag.test.py index 0c16e0b1d..7b34da133 100755 --- a/test/nag.test.py +++ b/test/nag.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -76,16 +77,16 @@ class TestNagging(TestCase): def test_nagging_ready(self): """Verify that nagging occurs when there are READY tasks of higher urgency""" - self.t("add one") # low urgency - self.t("add two due:10days scheduled:yesterday") # medium urgency, ready + self.t("add one") # low urgency + self.t("add two due:10days scheduled:yesterday") # medium urgency, ready code, out, err = self.t("1 done") self.assertIn("NAG", err) def test_nagging_not_ready(self): """Verify that nagging does not occur when there are unREADY tasks of higher urgency""" - self.t("add one") # low urgency - self.t("add two due:10days scheduled:10days") # medium urgency, not ready + self.t("add one") # low urgency + self.t("add two due:10days scheduled:10days") # medium urgency, not ready code, out, err = self.t("1 done") self.assertNotIn("NAG", err) @@ -156,6 +157,7 @@ class TestNagging(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/news.test.py b/test/news.test.py index e2caf8a2a..7f1aa5dcf 100755 --- a/test/news.test.py +++ b/test/news.test.py @@ -63,6 +63,7 @@ class TestNewsNag(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/obfuscate.test.py b/test/obfuscate.test.py index a4e401258..5ff0e78f8 100755 --- a/test/obfuscate.test.py +++ b/test/obfuscate.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -74,6 +75,7 @@ class TestObfuscation(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/oldest.test.py b/test/oldest.test.py index ac840ba7e..593a4e041 100755 --- a/test/oldest.test.py +++ b/test/oldest.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -117,6 +118,7 @@ class TestOldestAndNewest(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/operators.test.py b/test/operators.test.py index 9e121acdb..fcf4554d2 100755 --- a/test/operators.test.py +++ b/test/operators.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -441,6 +442,7 @@ class TestOperatorsQuantity(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/overdue.test.py b/test/overdue.test.py index cec542267..ac98c9279 100755 --- a/test/overdue.test.py +++ b/test/overdue.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -55,6 +56,7 @@ class TestOverdue(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/partial.test.py b/test/partial.test.py index 8467e1ce2..193f567f2 100755 --- a/test/partial.test.py +++ b/test/partial.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -41,17 +42,18 @@ class TestPartialMatch(TestCase): def test_partial_date_match_spaced(self): """Partial match for dates: today = now --> true""" - code, out, err = self.t('calc today = now') - self.assertIn('true', out) + code, out, err = self.t("calc today = now") + self.assertIn("true", out) def test_exact_date_match_spaced(self): """Exact match for dates: today == now --> false""" - code, out, err = self.t('calc today == now') - self.assertIn('false', out) + code, out, err = self.t("calc today == now") + self.assertIn("false", out) if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/prepend.test.py b/test/prepend.test.py index 97d57892a..2215ddbc2 100755 --- a/test/prepend.test.py +++ b/test/prepend.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -62,6 +63,7 @@ class TestPrepend(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/pri_sort.test.py b/test/pri_sort.test.py index 6e74a0519..25a19caf6 100755 --- a/test/pri_sort.test.py +++ b/test/pri_sort.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -110,6 +111,7 @@ class TestPrioritySorting(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/project.test.py b/test/project.test.py index 02d2d2880..c4718866d 100755 --- a/test/project.test.py +++ b/test/project.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -38,8 +39,10 @@ class TestProjects(TestCase): def setUp(self): self.t = Task() - self.STATUS = (r"The project '{0}' has changed\. " - r"Project '{0}' is {1} complete \({2} remaining\)\.") + self.STATUS = ( + r"The project '{0}' has changed\. " + r"Project '{0}' is {1} complete \({2} remaining\)\." + ) def test_project_summary_count(self): """'task projects' shouldn't consider deleted tasks in summary. @@ -58,46 +61,37 @@ class TestProjects(TestCase): """project status/progress is shown and is up-to-date""" code, out, err = self.t("add one pro:foo") - self.assertRegex(err, self.STATUS.format("foo", "0%", - "1 task")) + self.assertRegex(err, self.STATUS.format("foo", "0%", "1 task")) code, out, err = self.t("add two pro:foo") - self.assertRegex(err, self.STATUS.format("foo", "0%", - "2 of 2 tasks")) + self.assertRegex(err, self.STATUS.format("foo", "0%", "2 of 2 tasks")) code, out, err = self.t("add three pro:foo") - self.assertRegex(err, self.STATUS.format("foo", "0%", - "3 of 3 tasks")) + self.assertRegex(err, self.STATUS.format("foo", "0%", "3 of 3 tasks")) code, out, err = self.t("add four pro:foo") - self.assertRegex(err, self.STATUS.format("foo", "0%", - "4 of 4 tasks")) + self.assertRegex(err, self.STATUS.format("foo", "0%", "4 of 4 tasks")) code, out, err = self.t("1 done") - self.assertRegex(err, self.STATUS.format("foo", "25%", - "3 of 4 tasks")) + self.assertRegex(err, self.STATUS.format("foo", "25%", "3 of 4 tasks")) code, out, err = self.t("2 delete", input="y\n") - self.assertRegex(err, self.STATUS.format("foo", "33%", - "2 of 3 tasks")) + self.assertRegex(err, self.STATUS.format("foo", "33%", "2 of 3 tasks")) code, out, err = self.t("3 modify pro:bar") - self.assertRegex(err, self.STATUS.format("foo", "50%", - "1 of 2 tasks")) - self.assertRegex(err, self.STATUS.format("bar", "0%", - "1 task")) + self.assertRegex(err, self.STATUS.format("foo", "50%", "1 of 2 tasks")) + self.assertRegex(err, self.STATUS.format("bar", "0%", "1 task")) def test_project_spaces(self): """projects with spaces are handled correctly""" self.t("add hello pro:bob") code, out, err = self.t('1 mod pro:"foo bar"') - self.assertRegex(err, self.STATUS.format("foo bar", "0%", - "1 task")) + self.assertRegex(err, self.STATUS.format("foo bar", "0%", "1 task")) # Ensure filtering for project with spaces works code, out, err = self.t('pro:"foo bar" count') - self.assertEqual(out.strip(), '1') + self.assertEqual(out.strip(), "1") def test_project_spaces(self): """TW #2386: Filter for project:someday""" @@ -105,8 +99,8 @@ class TestProjects(TestCase): self.t("add hello pro:someday") # Ensure filtering for project with numeric date works - code, out, err = self.t('pro:someday count') - self.assertEqual(out.strip(), '1') + code, out, err = self.t("pro:someday count") + self.assertEqual(out.strip(), "1") def add_tasks(self): self.t("add testing project:existingParent") @@ -120,7 +114,7 @@ class TestProjects(TestCase): order = ( ".myProject ", ".myProject. ", - "abstractParent", # No space at EOL because this line in the summary ends here. + "abstractParent", # No space at EOL because this line in the summary ends here. " kid ", "existingParent ", " child ", @@ -136,8 +130,10 @@ class TestProjects(TestCase): self.assertTrue( lines[pos].startswith(proj), - msg=("Project '{0}' is not in line #{1} or has an unexpected " - "indentation.{2}".format(proj, pos, out)) + msg=( + "Project '{0}' is not in line #{1} or has an unexpected " + "indentation.{2}".format(proj, pos, out) + ), ) def test_project_indentation(self): @@ -321,7 +317,7 @@ class TestBug906(TestCase): def test_project_hierarchy_filter(self): """906: Test project hierarchy filters - Bug 906 + Bug 906 """ self.t("add zero") self.t("add one pro:a.b") @@ -355,7 +351,7 @@ class TestBug856(TestCase): def test_project_hierarchy_filter(self): """856: Test project.none: works - Bug 856: "task list project.none:" does not work. + Bug 856: "task list project.none:" does not work. """ self.t("add assigned project:X") self.t("add floating") @@ -364,7 +360,7 @@ class TestBug856(TestCase): self.assertIn("floating", out) self.assertNotIn("assigned", out) - code, out, err = self.t("project:\'\' ls") + code, out, err = self.t("project:'' ls") self.assertIn("floating", out) self.assertNotIn("assigned", out) @@ -380,7 +376,7 @@ class TestBug1511(TestCase): def test_project_hierarchy_filter(self): """1511: Test project:one-two can be added and queried - Bug 1511: Project titles not properly parsed if they contain hyphens + Bug 1511: Project titles not properly parsed if they contain hyphens """ self.t("add zero") self.t("add one project:two-three") @@ -396,7 +392,7 @@ class TestBug1455(TestCase): def test_project_hierarchy_filter(self): """1455: Test project:school) - Bug 1455: Filter parser does not properly handle parentheses in attributes + Bug 1455: Filter parser does not properly handle parentheses in attributes """ self.t("add zero") self.t("add one project:two)") @@ -431,16 +427,14 @@ class TestBug1267(TestCase): self.t = Task() def test_add_task_no_project_with_default(self): - """1267: Add a task without a project using direct rc change - """ + """1267: Add a task without a project using direct rc change""" project = "MakePudding" self.t("rc.default.project={0} add proj: 'Add cream'".format(project)) code, out, err = self.t("ls") self.assertNotIn(project, out) def test_add_task_no_project_with_default_rcfile(self): - """1267: Add a task without a project writing to rc file - """ + """1267: Add a task without a project writing to rc file""" project = "MakePudding" self.t.config("default.project", project) self.t("add proj: 'Add cream'") @@ -514,9 +508,7 @@ class TestBug1904(TestCase): self.t("add pro:a.b test2") def validate_order(self, out): - order = ("a", - " b", - "a-b") + order = ("a", " b", "a-b") lines = out.splitlines(True) # position where project names start on the lines list @@ -527,8 +519,10 @@ class TestBug1904(TestCase): self.assertTrue( lines[pos].startswith(proj), - msg=("Project '{0}' is not in line #{1} or has an unexpected " - "indentation.{2}".format(proj, pos, out)) + msg=( + "Project '{0}' is not in line #{1} or has an unexpected " + "indentation.{2}".format(proj, pos, out) + ), ) def test_project_eval(self): @@ -540,6 +534,7 @@ class TestBug1904(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/purge.test.py b/test/purge.test.py index ec6491fee..2518a8103 100755 --- a/test/purge.test.py +++ b/test/purge.test.py @@ -29,6 +29,7 @@ import sys import os import unittest import time + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -133,7 +134,7 @@ class TestDelete(TestCase): self.assertIn("Purged 4 tasks.", out) code, out, err = self.t("uuids") - self.assertEqual('\n', out) + self.assertEqual("\n", out) def test_purge_children_fail_pending(self): """Purge aborts if task has pending children""" @@ -154,7 +155,7 @@ class TestDelete(TestCase): # Check that nothing was purged code, out, err = self.t("count") - self.assertEqual('4\n', out) + self.assertEqual("4\n", out) def test_purge_children_fail_confirm(self): """Purge aborts if user does not agree with it affecting child tasks""" @@ -173,7 +174,7 @@ class TestDelete(TestCase): # Check that nothing was purged code, out, err = self.t("count") - self.assertEqual('4\n', out) + self.assertEqual("4\n", out) def test_purge_children(self): """Purge command removes dependencies on indirectly purged tasks""" @@ -202,8 +203,10 @@ class TestDelete(TestCase): dependencies = self.t("_get 1.depends")[1].strip() self.assertEqual("", dependencies) + if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/quotes.test.py b/test/quotes.test.py index 95b057231..c17e229e6 100755 --- a/test/quotes.test.py +++ b/test/quotes.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -124,34 +125,35 @@ class TestBug1436(TestCase): def test_backslashes(self): """1436: Prove to the reader that backslashes are eaten twice (which means - two backslashes to one) once by Python, and once more by some mystery process - launch thing. + two backslashes to one) once by Python, and once more by some mystery process + launch thing. - This problem is entirely testing artifact, and not Taskwarrior. + This problem is entirely testing artifact, and not Taskwarrior. """ self.echo = Task(taskw=utils.binary_location("echo", USE_PATH=True)) # One level of backshashes gets eaten by bash # Verify with: $ echo xxx \\\\yyy zzz - code, out, err = self.echo(r"xxx \\\\yyy zzz") # Shows as 'xxx \\yyy zzz' - code, out, err = self.echo(r"xxx \\yyy zzz") # Shows as 'xxx \yyy zzz' - code, out, err = self.echo(r"xxx \yyy zzz") # Shows as 'xxx yyy zzz' + code, out, err = self.echo(r"xxx \\\\yyy zzz") # Shows as 'xxx \\yyy zzz' + code, out, err = self.echo(r"xxx \\yyy zzz") # Shows as 'xxx \yyy zzz' + code, out, err = self.echo(r"xxx \yyy zzz") # Shows as 'xxx yyy zzz' # If single quotes are used, the backslashes are not eaten # Verify with: $ echo xxx '\\\\yyy' zzz - code, out, err = self.echo(r"xxx '\\\\yyy' zzz") # Shows as 'xxx \\\\yyy zzz' - code, out, err = self.echo(r"xxx '\\yyy' zzz") # Shows as 'xxx \\yyy zzz' - code, out, err = self.echo(r"xxx '\yyy' zzz") # Shows as 'xxx \yyy zzz' + code, out, err = self.echo(r"xxx '\\\\yyy' zzz") # Shows as 'xxx \\\\yyy zzz' + code, out, err = self.echo(r"xxx '\\yyy' zzz") # Shows as 'xxx \\yyy zzz' + code, out, err = self.echo(r"xxx '\yyy' zzz") # Shows as 'xxx \yyy zzz' # If double quotes are used, the backslashes are eaten # Verify with: $ echo xxx "\\\\yyy" zzz - code, out, err = self.echo(r'xxx "\\\\yyy" zzz') # Shows as 'xxx \\\\yyy zzz' - code, out, err = self.echo(r'xxx "\\yyy" zzz') # Shows as 'xxx \\yyy zzz' - code, out, err = self.echo(r'xxx "\yyy" zzz') # Shows as 'xxx \yyy zzz' + code, out, err = self.echo(r'xxx "\\\\yyy" zzz') # Shows as 'xxx \\\\yyy zzz' + code, out, err = self.echo(r'xxx "\\yyy" zzz') # Shows as 'xxx \\yyy zzz' + code, out, err = self.echo(r'xxx "\yyy" zzz') # Shows as 'xxx \yyy zzz' if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/rc.override.test.py b/test/rc.override.test.py index 55e748ac8..ce83dacd2 100755 --- a/test/rc.override.test.py +++ b/test/rc.override.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -39,7 +40,7 @@ class TestOverride(TestCase): def setUp(self): """Executed before each test in the class""" self.t = Task() - self.t.config("regex", "0") + self.t.config("regex", "0") self.t.config("verbose", "nothing") def test_override(self): @@ -71,6 +72,7 @@ class TestRCSegfault(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/recurrence.test.py b/test/recurrence.test.py index d65a35c63..155eb9d1f 100755 --- a/test/recurrence.test.py +++ b/test/recurrence.test.py @@ -30,6 +30,7 @@ import os import re import time import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -41,12 +42,12 @@ class TestRecurrenceSorting(TestCase): def setUpClass(cls): """Executed once before any test in the class""" cls.t = Task() - cls.t.config("report.asc.columns", "id,recur,description") - cls.t.config("report.asc.sort", "recur+") - cls.t.config("report.asc.filter", "status:pending") + cls.t.config("report.asc.columns", "id,recur,description") + cls.t.config("report.asc.sort", "recur+") + cls.t.config("report.asc.filter", "status:pending") cls.t.config("report.desc.columns", "id,recur,description") - cls.t.config("report.desc.sort", "recur-") - cls.t.config("report.desc.filter", "status:pending") + cls.t.config("report.desc.sort", "recur-") + cls.t.config("report.desc.filter", "status:pending") cls.t("add one due:tomorrow recur:daily") cls.t("add two due:tomorrow recur:weekly") @@ -205,6 +206,7 @@ class TestRecurrenceTasks(TestCase): code, out, err = self.t("3 delete", input="y\n") self.assertIn("Deleted 1 task.", out) + class TestBug972(TestCase): def setUp(self): """972: Executed before each test in the class""" @@ -212,7 +214,7 @@ class TestBug972(TestCase): def test_interpretation_of_seven(self): """Bug 972: A recurrence period of "7" is interpreted as "7s", not "7d" - as intended. + as intended. """ code, out, err = self.t.runError("add one due:now recur:2") self.assertIn("The duration value '2' is not supported.", err) @@ -226,7 +228,7 @@ class TestDeletionRecurrence(TestCase): def test_delete_parent(self): """Delete a parent with child tasks""" self.t("add one due:eom recur:daily") - self.t("list") # GC/handleRecurrence + self.t("list") # GC/handleRecurrence code, out, err = self.t("1 delete", input="y\ny\n") self.assertIn("Deleted 2 tasks.", out) @@ -237,7 +239,7 @@ class TestDeletionRecurrence(TestCase): """Delete a child with sibling tasks""" self.t("add one due:eom recur:daily") self.t("list rc.recurrence.limit:5") - code, out, err = self.t("list rc.verbose:nothing") # GC/handleRecurrence + code, out, err = self.t("list rc.verbose:nothing") # GC/handleRecurrence self.assertEqual(out.count("one"), 5) code, out, err = self.t("2 delete", input="y\ny\n") @@ -252,7 +254,7 @@ class TestAppendPrependRecurrence(TestCase): def test_append_propagate(self): """Append and propagate""" self.t("add one due:eom recur:daily") - self.t("list rc.recurrence.limit:2") # GC/handleRecurrence + self.t("list rc.recurrence.limit:2") # GC/handleRecurrence code, out, err = self.t("2 append APP", input="y\n") self.assertIn("Appended 2 tasks.", out) @@ -260,7 +262,7 @@ class TestAppendPrependRecurrence(TestCase): def test_prepend_propagate(self): """Prepend and propagate""" self.t("add one due:eom recur:daily") - self.t("list rc.recurrence.limit:2") # GC/handleRecurrence + self.t("list rc.recurrence.limit:2") # GC/handleRecurrence code, out, err = self.t("2 prepend PRE", input="y\n") self.assertIn("Prepended 2 tasks.", out) @@ -359,11 +361,12 @@ class TestBug955(TestCase): self.assertIn("Deleted 2 tasks", out) code, out, err = self.t.runError("all status:recurring") - self.assertIn("No matches", err) + self.assertIn("No matches", err) code, out, err = self.t.runError("ls") self.assertIn("No matches", err) + class TestUpgradeToRecurring(TestCase): def setUp(self): """Executed before each test in the class""" @@ -383,6 +386,7 @@ class TestUpgradeToRecurring(TestCase): code, out, err = self.t.runError("1 modify recur:weekly") self.assertIn("You cannot specify a recurring task without a due date.", err) + class TestRecurrenceNotification(TestCase): def setUp(self): """Executed before each test in the class""" @@ -399,6 +403,7 @@ class TestRecurrenceNotification(TestCase): code, out, err = self.t("list") self.assertNotIn("Creating recurring task instance 'foo'", err) + class BaseTestBug360(TestCase): def setUp(self): """Executed before each test in the class""" @@ -407,10 +412,10 @@ class BaseTestBug360(TestCase): # This command forces a handleRecurrence() call to generate synthetic tasks. self.t("ls") + class TestBug360RemovalError(BaseTestBug360): def test_modify_recursive_project(self): - """360: Modifying a recursive task by adding project: also modifies parent - """ + """360: Modifying a recursive task by adding project: also modifies parent""" code, out, err = self.t("1 modify project:bar", input="y\n") expected = "Modified 2 tasks." @@ -419,8 +424,7 @@ class TestBug360RemovalError(BaseTestBug360): self.assertNotIn(expected, err) def test_cannot_remove_recurrence(self): - """360: Cannot remove recurrence from recurring task - """ + """360: Cannot remove recurrence from recurring task""" # TODO Removing recur: from a recurring task should also remove imask # and parent. @@ -432,8 +436,7 @@ class TestBug360RemovalError(BaseTestBug360): self.assertIn(expected, err) def test_cannot_remove_due_date(self): - """360: Cannot remove due date from recurring task - """ + """360: Cannot remove due date from recurring task""" # TODO Removing due: from a recurring task should also remove recur, # imask and parent code, out, err = self.t.runError("2 modify due:") @@ -470,6 +473,7 @@ class TestBug360AllowedChanges(BaseTestBug360): expected = "You cannot remove the due date from a recurring task." self.assertNotIn(expected, err) + class TestBug649(TestCase): def setUp(self): """Executed before each test in the class""" @@ -482,6 +486,7 @@ class TestBug649(TestCase): self.assertIn("is neither pending nor waiting", out) self.assertNotIn("Completed 1", out) + class TestBugC001(TestCase): def setUp(self): """Executed before each test in the class""" @@ -492,6 +497,7 @@ class TestBugC001(TestCase): code, out, err = self.t("add one due:tomorrow recur:daily") code, out, err = self.t("add two due:tomorrow recur:daily") + class TestBug839(TestCase): def setUp(self): """Executed before each test in the class""" @@ -501,7 +507,10 @@ class TestBug839(TestCase): """839: Verify that importing a legacy recurrence value is ok""" # use a recent timestamp to avoid slowly iterating over large number of tasks justnow = int(time.time()) - 120 - json = '{"description":"one","due":"%s","recur":"1m","status":"recurring","uuid":"ebeeab00-ccf8-464b-8b58-f7f2d606edfb"}' % justnow + json = ( + '{"description":"one","due":"%s","recur":"1m","status":"recurring","uuid":"ebeeab00-ccf8-464b-8b58-f7f2d606edfb"}' + % justnow + ) self.t("import -", input=json) code, out, err = self.t("list") @@ -519,75 +528,76 @@ class TestPeriod(TestCase): self.t = Task() def test_recurrence_periods(self): - """Verify recurrence period special-case support + """Verify recurrence period special-case support - Date getNextRecurrence (Date& current, std::string& period) + Date getNextRecurrence (Date& current, std::string& period) - Confirmed: - getNextRecurrence convertDuration - ----------------- --------------- - daily - day - weekly - sennight - biweekly - fortnight - monthly monthly - quarterly quarterly - semiannual semiannual - bimonthly bimonthly - biannual biannual - biyearly biyearly - annual - yearly - *m *m - *q *q - *d - *w - *y - """ + Confirmed: + getNextRecurrence convertDuration + ----------------- --------------- + daily + day + weekly + sennight + biweekly + fortnight + monthly monthly + quarterly quarterly + semiannual semiannual + bimonthly bimonthly + biannual biannual + biyearly biyearly + annual + yearly + *m *m + *q *q + *d + *w + *y + """ - self.t("add daily due:tomorrow recur:daily") - self.t("add 1day due:tomorrow recur:1day") - self.t("add weekly due:tomorrow recur:weekly") - self.t("add 1sennight due:tomorrow recur:1sennight") - self.t("add biweekly due:tomorrow recur:biweekly") - self.t("add fortnight due:tomorrow recur:fortnight") - self.t("add monthly due:tomorrow recur:monthly") - self.t("add quarterly due:tomorrow recur:quarterly") - self.t("add semiannual due:tomorrow recur:semiannual") - self.t("add bimonthly due:tomorrow recur:bimonthly") - self.t("add biannual due:tomorrow recur:biannual") - self.t("add biyearly due:tomorrow recur:biyearly") - self.t("add annual due:tomorrow recur:annual") - self.t("add yearly due:tomorrow recur:yearly") - self.t("add 2d due:tomorrow recur:2d") - self.t("add 2w due:tomorrow recur:2w") - self.t("add 2mo due:tomorrow recur:2mo") - self.t("add 2q due:tomorrow recur:2q") - self.t("add 2y due:tomorrow recur:2y") + self.t("add daily due:tomorrow recur:daily") + self.t("add 1day due:tomorrow recur:1day") + self.t("add weekly due:tomorrow recur:weekly") + self.t("add 1sennight due:tomorrow recur:1sennight") + self.t("add biweekly due:tomorrow recur:biweekly") + self.t("add fortnight due:tomorrow recur:fortnight") + self.t("add monthly due:tomorrow recur:monthly") + self.t("add quarterly due:tomorrow recur:quarterly") + self.t("add semiannual due:tomorrow recur:semiannual") + self.t("add bimonthly due:tomorrow recur:bimonthly") + self.t("add biannual due:tomorrow recur:biannual") + self.t("add biyearly due:tomorrow recur:biyearly") + self.t("add annual due:tomorrow recur:annual") + self.t("add yearly due:tomorrow recur:yearly") + self.t("add 2d due:tomorrow recur:2d") + self.t("add 2w due:tomorrow recur:2w") + self.t("add 2mo due:tomorrow recur:2mo") + self.t("add 2q due:tomorrow recur:2q") + self.t("add 2y due:tomorrow recur:2y") + + # Verify that the recurring task instances were created. One of each. + code, out, err = self.t("list") + self.assertIn(" daily ", out) + self.assertIn(" 1day ", out) + self.assertIn(" weekly ", out) + self.assertIn(" 1sennight ", out) + self.assertIn(" biweekly ", out) + self.assertIn(" fortnight ", out) + self.assertIn(" monthly ", out) + self.assertIn(" quarterly ", out) + self.assertIn(" semiannual ", out) + self.assertIn(" bimonthly ", out) + self.assertIn(" biannual ", out) + self.assertIn(" biyearly ", out) + self.assertIn(" annual ", out) + self.assertIn(" yearly ", out) + self.assertIn(" 2d ", out) + self.assertIn(" 2w ", out) + self.assertIn(" 2mo ", out) + self.assertIn(" 2q ", out) + self.assertIn(" 2y ", out) - # Verify that the recurring task instances were created. One of each. - code, out, err = self.t("list") - self.assertIn(" daily ", out); - self.assertIn(" 1day ", out); - self.assertIn(" weekly ", out); - self.assertIn(" 1sennight ", out); - self.assertIn(" biweekly ", out); - self.assertIn(" fortnight ", out); - self.assertIn(" monthly ", out); - self.assertIn(" quarterly ", out); - self.assertIn(" semiannual ", out); - self.assertIn(" bimonthly ", out); - self.assertIn(" biannual ", out); - self.assertIn(" biyearly ", out); - self.assertIn(" annual ", out); - self.assertIn(" yearly ", out); - self.assertIn(" 2d ", out); - self.assertIn(" 2w ", out); - self.assertIn(" 2mo ", out); - self.assertIn(" 2q ", out); - self.assertIn(" 2y ", out); class TestBugAnnual(TestCase): def setUp(self): @@ -596,11 +606,11 @@ class TestBugAnnual(TestCase): def test_annual_creep(self): """Verify 'annual' recurring tasks don't creep""" - self.t.config("dateformat", "YMD") - self.t.config("report.annual.labels", "ID,Due") + self.t.config("dateformat", "YMD") + self.t.config("report.annual.labels", "ID,Due") self.t.config("report.annual.columns", "id,due") - self.t.config("report.annual.filter", "status:pending") - self.t.config("report.annual.sort", "due+") + self.t.config("report.annual.filter", "status:pending") + self.t.config("report.annual.sort", "due+") # If a task is added with a due date ten years ago, with an annual recurrence, # then the synthetic tasks in between then and now have a due date that creeps. @@ -647,6 +657,7 @@ class TestBugAnnual(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/reports.test.py b/test/reports.test.py index 4a18c3bb5..b1d763ae7 100755 --- a/test/reports.test.py +++ b/test/reports.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -54,6 +55,7 @@ class TestReportCommand(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/scripts/test_macos.sh b/test/scripts/test_macos.sh index cc86ece07..b471a7e1c 100755 --- a/test/scripts/test_macos.sh +++ b/test/scripts/test_macos.sh @@ -14,4 +14,4 @@ pushd test make ./run_all -v cat all.log | grep 'not ok' -./problems \ No newline at end of file +./problems diff --git a/test/search.test.py b/test/search.test.py index 51474208e..6be972f86 100755 --- a/test/search.test.py +++ b/test/search.test.py @@ -29,6 +29,7 @@ import sys import os import unittest import platform + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -47,7 +48,7 @@ class TestSearch(TestCase): def test_plain_arg(self): """Verify plain args are interpreted as search terms - tw-1635: Running "task anystringatall" does not filter anything + tw-1635: Running "task anystringatall" does not filter anything """ code, out, err = self.t("one list") self.assertIn("one", out) @@ -65,6 +66,7 @@ class TestSearch(TestCase): self.assertIn("one", out) self.assertNotIn("two", out) + class Test1418(TestCase): def setUp(self): self.t = Task() @@ -140,6 +142,7 @@ class Test1418(TestCase): code, out, err = self.t("/foo\\+/") self.assertIn(description, out) + class TestBug1472(TestCase): @classmethod def setUpClass(cls): @@ -180,67 +183,74 @@ class TestBug1472(TestCase): class Test1469(TestCase): def setUp(self): self.t = Task() - self.t('add foo') + self.t("add foo") self.t('add "neue Badmöbel kaufen"') def test_implicit_search_sensitive_regex(self): - """1469: Implicit search, case sensitive, regex """ - code, out, err = self.t('list /möbel/ rc.search.case.sensitive=yes rc.regex=on') + """1469: Implicit search, case sensitive, regex""" + code, out, err = self.t("list /möbel/ rc.search.case.sensitive=yes rc.regex=on") self.assertEqual(0, code, "Exit code was non-zero ({0})".format(code)) - self.assertIn('möbel', out) - self.assertNotIn('foo', out) + self.assertIn("möbel", out) + self.assertNotIn("foo", out) def test_implicit_search_sensitive_noregex(self): - """1469: Implicit search, case sensitive, no regex """ - code, out, err = self.t('list /möbel/ rc.search.case.sensitive=yes rc.regex=off') + """1469: Implicit search, case sensitive, no regex""" + code, out, err = self.t( + "list /möbel/ rc.search.case.sensitive=yes rc.regex=off" + ) self.assertEqual(0, code, "Exit code was non-zero ({0})".format(code)) - self.assertIn('möbel', out) - self.assertNotIn('foo', out) + self.assertIn("möbel", out) + self.assertNotIn("foo", out) - @unittest.skipIf('CYGWIN' in platform.system(), 'Skipping regex case-insensitive test for Cygwin') + @unittest.skipIf( + "CYGWIN" in platform.system(), "Skipping regex case-insensitive test for Cygwin" + ) def test_implicit_search_insensitive_regex(self): - """1469: Implicit search, case insensitive, regex """ - code, out, err = self.t('list /möbel/ rc.search.case.sensitive=no rc.regex=on') - self.assertEqual(0, code, - "Exit code was non-zero ({0})".format(code)) - self.assertIn('möbel', out) - self.assertNotIn('foo', out) + """1469: Implicit search, case insensitive, regex""" + code, out, err = self.t("list /möbel/ rc.search.case.sensitive=no rc.regex=on") + self.assertEqual(0, code, "Exit code was non-zero ({0})".format(code)) + self.assertIn("möbel", out) + self.assertNotIn("foo", out) def test_implicit_search_insensitive_noregex(self): - """1469: Implicit search, case insensitive, no regex """ - code, out, err = self.t('list /möbel/ rc.search.case.sensitive=no rc.regex=off') + """1469: Implicit search, case insensitive, no regex""" + code, out, err = self.t("list /möbel/ rc.search.case.sensitive=no rc.regex=off") self.assertEqual(0, code, "Exit code was non-zero ({0})".format(code)) - self.assertIn('möbel', out) - self.assertNotIn('foo', out) + self.assertIn("möbel", out) + self.assertNotIn("foo", out) def test_explicit_search_sensitive_regex(self): - """1469: Explicit search, case sensitive, regex """ - code, out, err = self.t('list /möbel/ rc.search.case.sensitive=yes rc.regex=on') + """1469: Explicit search, case sensitive, regex""" + code, out, err = self.t("list /möbel/ rc.search.case.sensitive=yes rc.regex=on") self.assertEqual(0, code, "Exit code was non-zero ({0})".format(code)) - self.assertIn('möbel', out) - self.assertNotIn('foo', out) + self.assertIn("möbel", out) + self.assertNotIn("foo", out) def test_explicit_search_sensitive_noregex(self): - """1469: Explicit search, case sensitive, no regex """ - code, out, err = self.t('list /möbel/ rc.search.case.sensitive=yes rc.regex=off') + """1469: Explicit search, case sensitive, no regex""" + code, out, err = self.t( + "list /möbel/ rc.search.case.sensitive=yes rc.regex=off" + ) self.assertEqual(0, code, "Exit code was non-zero ({0})".format(code)) - self.assertIn('möbel', out) - self.assertNotIn('foo', out) + self.assertIn("möbel", out) + self.assertNotIn("foo", out) - @unittest.skipIf('CYGWIN' in platform.system(), 'Skipping regex case-insensitive test for Cygwin') + @unittest.skipIf( + "CYGWIN" in platform.system(), "Skipping regex case-insensitive test for Cygwin" + ) def test_explicit_search_insensitive_regex(self): - """1469: Explicit search, case insensitive, regex """ - code, out, err = self.t('list /möbel/ rc.search.case.sensitive=no rc.regex=on') + """1469: Explicit search, case insensitive, regex""" + code, out, err = self.t("list /möbel/ rc.search.case.sensitive=no rc.regex=on") self.assertEqual(0, code, "Exit code was non-zero ({0})".format(code)) - self.assertIn('möbel', out) - self.assertNotIn('foo', out) + self.assertIn("möbel", out) + self.assertNotIn("foo", out) def test_explicit_search_insensitive_noregex(self): - """1469: Explicit search, case insensitive, no regex """ - code, out, err = self.t('list /möbel/ rc.search.case.sensitive=no rc.regex=off') + """1469: Explicit search, case insensitive, no regex""" + code, out, err = self.t("list /möbel/ rc.search.case.sensitive=no rc.regex=off") self.assertEqual(0, code, "Exit code was non-zero ({0})".format(code)) - self.assertIn('möbel', out) - self.assertNotIn('foo', out) + self.assertIn("möbel", out) + self.assertNotIn("foo", out) class TestBug1479(TestCase): @@ -272,6 +282,7 @@ class TestBug1479(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/sequence.test.py b/test/sequence.test.py index add63b362..2943fdac2 100755 --- a/test/sequence.test.py +++ b/test/sequence.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -57,7 +58,10 @@ class TestSequences(TestCase): """Test sequences in start/stop""" self.t("1,2 start") code, out, err = self.t("_get 1.start 2.start") - self.assertRegex(out, "\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2} \\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\n") + self.assertRegex( + out, + "\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2} \\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\n", + ) self.t("1,2 stop") code, out, err = self.t("_get 1.start 2.start") @@ -84,12 +88,15 @@ class TestSequences(TestCase): def test_sequence_annotate(self): """Test sequences in annotate""" self.t("1,2 annotate note") - code, out, err = self.t("_get 1.annotations.1.description 2.annotations.1.description") + code, out, err = self.t( + "_get 1.annotations.1.description 2.annotations.1.description" + ) self.assertEqual("note note\n", out) if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/shell.test.py b/test/shell.test.py index 8c1853b18..1e4d212a5 100755 --- a/test/shell.test.py +++ b/test/shell.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -40,19 +41,20 @@ class TestFilterPrefix(TestCase): """Executed once before any test in the class""" cls.t = Task() cls.t.config("verbose", "nothing") - cls.t('add foo') + cls.t("add foo") def test_success(self): """Test successful search returns zero.""" - code, out, err = self.t('list /foo/') + code, out, err = self.t("list /foo/") def test_failure(self): """Test failed search returns non-zero.""" - code, out, err = self.t.runError('list /bar/') + code, out, err = self.t.runError("list /bar/") if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/show.test.py b/test/show.test.py index 11a091bf8..f3fdceb79 100755 --- a/test/show.test.py +++ b/test/show.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -68,7 +69,9 @@ class TestShowCommand(TestCase): """Verify show command lists all with no arg provided""" self.t.config("foo", "bar") code, out, err = self.t("show") - self.assertIn("Your .taskrc file contains these unrecognized variables:\n foo", out) + self.assertIn( + "Your .taskrc file contains these unrecognized variables:\n foo", out + ) class TestShowHelperCommand(TestCase): @@ -85,6 +88,7 @@ class TestShowHelperCommand(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/simpletap/CMakeLists.txt b/test/simpletap/CMakeLists.txt index 040a465d6..53303a1f5 100644 --- a/test/simpletap/CMakeLists.txt +++ b/test/simpletap/CMakeLists.txt @@ -1 +1 @@ -configure_file(__init__.py __init__.py COPYONLY) \ No newline at end of file +configure_file(__init__.py __init__.py COPYONLY) diff --git a/test/simpletap/__init__.py b/test/simpletap/__init__.py index 72b1fe690..4134f8f21 100644 --- a/test/simpletap/__init__.py +++ b/test/simpletap/__init__.py @@ -80,8 +80,7 @@ class TAPTestResult(unittest.result.TestResult): pass def _restoreStdout(self): - """Restore sys.stdout and sys.stderr, don't merge buffered output yet - """ + """Restore sys.stdout and sys.stderr, don't merge buffered output yet""" if self.buffer: sys.stdout = self._original_stdout sys.stderr = self._original_stderr @@ -99,12 +98,11 @@ class TAPTestResult(unittest.result.TestResult): else: stream.write("# " + line) - if not line.endswith('\n'): - stream.write('\n') + if not line.endswith("\n"): + stream.write("\n") def _mergeStdout(self): - """Merge buffered output with main streams - """ + """Merge buffered output with main streams""" if self.buffer: output = self._stdout_buffer.getvalue() @@ -154,25 +152,33 @@ class TAPTestResult(unittest.result.TestResult): if status: if status == "SKIP": - self.stream.writeln("{0} {1} - {2}: {3} # skip".format( - color("ok", "yellow"), self.testsRun, filename, desc) + self.stream.writeln( + "{0} {1} - {2}: {3} # skip".format( + color("ok", "yellow"), self.testsRun, filename, desc + ) ) elif status == "EXPECTED_FAILURE": - self.stream.writeln("{0} {1} - {2}: {3} # TODO".format( - color("not ok", "yellow"), self.testsRun, filename, desc) + self.stream.writeln( + "{0} {1} - {2}: {3} # TODO".format( + color("not ok", "yellow"), self.testsRun, filename, desc + ) ) elif status == "UNEXPECTED_SUCCESS": - self.stream.writeln("{0} {1} - {2}: {3} # FIXED".format( - color("not ok", "yellow"), self.testsRun, filename, desc) + self.stream.writeln( + "{0} {1} - {2}: {3} # FIXED".format( + color("not ok", "yellow"), self.testsRun, filename, desc + ) ) else: - self.stream.writeln("{0} {1} - {2}: {3}".format( - color("not ok", "red"), self.testsRun, filename, desc) + self.stream.writeln( + "{0} {1} - {2}: {3}".format( + color("not ok", "red"), self.testsRun, filename, desc + ) ) if exception_name: - self.stream.writeln("# {0}: {1}{2}:".format( - status, exception_name, trace_msg) + self.stream.writeln( + "# {0}: {1}{2}:".format(status, exception_name, trace_msg) ) else: self.stream.writeln("# {0}:".format(status)) @@ -185,8 +191,10 @@ class TAPTestResult(unittest.result.TestResult): line = line.replace("\\n", "\n# ") self.stream.writeln("#{0}{1}".format(padding, line)) else: - self.stream.writeln("{0} {1} - {2}: {3}".format( - color("ok", "green"), self.testsRun, filename, desc) + self.stream.writeln( + "{0} {1} - {2}: {3}".format( + color("ok", "green"), self.testsRun, filename, desc + ) ) # Flush all buffers to stdout @@ -223,6 +231,7 @@ class TAPTestRunner(unittest.runner.TextTestRunner): Inherits from TextTestRunner the default runner. """ + resultclass = TAPTestResult def __init__(self, stream=sys.stdout, *args, **kwargs): diff --git a/test/sorting.test.py b/test/sorting.test.py index 67799e0a4..f8927d04f 100755 --- a/test/sorting.test.py +++ b/test/sorting.test.py @@ -30,6 +30,7 @@ import os import re import unittest import time + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -43,6 +44,7 @@ class MetaTestSorting(MetaTest): Creates test_methods in the TestCase class dynamically named after the filter used. """ + @staticmethod def make_function(classname, *args, **kwargs): _filter, expectations = args @@ -82,123 +84,117 @@ class TestSorting(TestCase): TESTS = ( # Filter # Expected matches/outputs - # Single sort column. - ('priority-', ('(?:one.+four|four.+one).+two.+three.+zero',)), - ('priority+', ('zero.+three.+two.+(?:one.+four|four.+one)',)), - ('project-', ('(?:three.+four|four.+three).+two.+one.+zero',)), - ('project+', ('zero.+one.+two.+(?:three.+four|four.+three)',)), - ('start-', ('one.+zero', 'one.+two', 'one.+three', 'one.+four',)), - ('start+', ('one.+zero', 'one.+two', 'one.+three', 'one.+four',)), - ('due-', ('three.+(?:two.+four|four.+two).+one.+zero',)), - ('due+', ('one.+(?:two.+four|four.+two).+three.+zero',)), - ('description-', ('zero.+two.+three.+one.+four',)), - ('description+', ('four.+one.+three.+two.+zero',)), - + ("priority-", ("(?:one.+four|four.+one).+two.+three.+zero",)), + ("priority+", ("zero.+three.+two.+(?:one.+four|four.+one)",)), + ("project-", ("(?:three.+four|four.+three).+two.+one.+zero",)), + ("project+", ("zero.+one.+two.+(?:three.+four|four.+three)",)), + ( + "start-", + ( + "one.+zero", + "one.+two", + "one.+three", + "one.+four", + ), + ), + ( + "start+", + ( + "one.+zero", + "one.+two", + "one.+three", + "one.+four", + ), + ), + ("due-", ("three.+(?:two.+four|four.+two).+one.+zero",)), + ("due+", ("one.+(?:two.+four|four.+two).+three.+zero",)), + ("description-", ("zero.+two.+three.+one.+four",)), + ("description+", ("four.+one.+three.+two.+zero",)), # Two sort columns. - ('priority-,project-', ('four.+one.+two.+three.+zero',)), - ('priority-,project+', ('one.+four.+two.+three.+zero',)), - ('priority+,project-', ('zero.+three.+two.+four.+one',)), - ('priority+,project+', ('zero.+three.+two.+one.+four',)), - - ('priority-,start-', ('one.+four.+two.+three.+zero',)), - ('priority-,start+', ('one.+four.+two.+three.+zero',)), - ('priority+,start-', ('zero.+three.+two.+one.+four',)), - ('priority+,start+', ('zero.+three.+two.+one.+four',)), - - ('priority-,due-', ('four.+one.+two.+three.+zero',)), - ('priority-,due+', ('one.+four.+two.+three.+zero',)), - ('priority+,due-', ('zero.+three.+two.+four.+one',)), - ('priority+,due+', ('zero.+three.+two.+one.+four',)), - - ('priority-,description-', ('one.+four.+two.+three.+zero',)), - ('priority-,description+', ('four.+one.+two.+three.+zero',)), - ('priority+,description-', ('zero.+three.+two.+one.+four',)), - ('priority+,description+', ('zero.+three.+two.+four.+one',)), - - ('project-,priority-', ('four.+three.+two.+one.+zero',)), - ('project-,priority+', ('three.+four.+two.+one.+zero',)), - ('project+,priority-', ('zero.+one.+two.+four.+three',)), - ('project+,priority+', ('zero.+one.+two.+three.+four',)), - - ('project-,start-', ('three.+four.+two.+one.+zero',)), - ('project-,start+', ('(?:four.+three|three.+four).+two.+one.+zero',)), - ('project+,start-', ('zero.+one.+two.+three.+four',)), - ('project+,start+', ('zero.+one.+two.+(?:four.+three|three.+four)',)), - - ('project-,due-', ('three.+four.+two.+one.+zero',)), - ('project-,due+', ('four.+three.+two.+one.+zero',)), - ('project+,due-', ('zero.+one.+two.+three.+four',)), - ('project+,due+', ('zero.+one.+two.+four.+three',)), - - ('project-,description-', ('three.+four.+two.+one.+zero',)), - ('project-,description+', ('four.+three.+two.+one.+zero',)), - ('project+,description-', ('zero.+one.+two.+three.+four',)), - ('project+,description+', ('zero.+one.+two.+four.+three',)), - - ('start-,priority-', ('one.+four.+two.+three.+zero',)), - ('start-,priority+', ('one.+zero.+three.+two.+four',)), - ('start+,priority-', ('one.+four.+two.+three.+zero',)), - ('start+,priority+', ('one.+zero.+three.+two.+four',)), - - ('start-,project-', ('one.+(?:three.+four|four.+three).+two.+zero',)), - ('start-,project+', ('one.+zero.+two.+(?:three.+four|four.+three)',)), - ('start+,project-', ('one.+(?:three.+four|four.+three).+two.+zero',)), - ('start+,project+', ('one.+zero.+two.+(?:three.+four|four.+three)',)), - - ('start-,due-', ('one.+three.+(?:four.+two|two.+four).+zero',)), - ('start-,due+', ('one.+(?:four.+two|two.+four).+three.+zero',)), - ('start+,due-', ('one.+three.+(?:four.+two|two.+four).+zero',)), - ('start+,due+', ('one.+(?:four.+two|two.+four).+three.+zero',)), - - ('start-,description-', ('one.+zero.+two.+three.+four',)), - ('start-,description+', ('one.+four.+three.+two.+zero',)), - ('start+,description-', ('one.+zero.+two.+three.+four',)), - ('start+,description+', ('one.+four.+three.+two.+zero',)), - - ('due-,priority-', ('three.+four.+two.+one.+zero',)), - ('due-,priority+', ('three.+two.+four.+one.+zero',)), - ('due+,priority-', ('one.+four.+two.+three.+zero',)), - ('due+,priority+', ('one.+two.+four.+three.+zero',)), - - ('due-,project-', ('three.+four.+two.+one.+zero',)), - ('due-,project+', ('three.+two.+four.+one.+zero',)), - ('due+,project-', ('one.+four.+two.+three.+zero',)), - ('due+,project+', ('one.+two.+four.+three.+zero',)), - - ('due-,start-', ('three.+(?:four.+two|two.+four).+one.+zero',)), - ('due-,start+', ('three.+(?:four.+two|two.+four).+one.+zero',)), - ('due+,start-', ('one.+(?:four.+two|two.+four).+three.+zero',)), - ('due+,start+', ('one.+(?:four.+two|two.+four).+three.+zero',)), - - ('due-,description-', ('three.+two.+four.+one.+zero',)), - ('due-,description+', ('three.+four.+two.+one.+zero',)), - ('due+,description-', ('one.+two.+four.+three.+zero',)), - ('due+,description+', ('one.+four.+two.+three.+zero',)), - - ('description-,priority-', ('zero.+two.+three.+one.+four',)), - ('description-,priority+', ('zero.+two.+three.+one.+four',)), - ('description+,priority-', ('four.+one.+three.+two.+zero',)), - ('description+,priority+', ('four.+one.+three.+two.+zero',)), - - ('description-,project-', ('zero.+two.+three.+one.+four',)), - ('description-,project+', ('zero.+two.+three.+one.+four',)), - ('description+,project-', ('four.+one.+three.+two.+zero',)), - ('description+,project+', ('four.+one.+three.+two.+zero',)), - - ('description-,start-', ('zero.+two.+three.+one.+four',)), - ('description-,start+', ('zero.+two.+three.+one.+four',)), - ('description+,start-', ('four.+one.+three.+two.+zero',)), - ('description+,start+', ('four.+one.+three.+two.+zero',)), - - ('description-,due-', ('zero.+two.+three.+one.+four',)), - ('description-,due+', ('zero.+two.+three.+one.+four',)), - ('description+,due-', ('four.+one.+three.+two.+zero',)), - ('description+,due+', ('four.+one.+three.+two.+zero',)), - + ("priority-,project-", ("four.+one.+two.+three.+zero",)), + ("priority-,project+", ("one.+four.+two.+three.+zero",)), + ("priority+,project-", ("zero.+three.+two.+four.+one",)), + ("priority+,project+", ("zero.+three.+two.+one.+four",)), + ("priority-,start-", ("one.+four.+two.+three.+zero",)), + ("priority-,start+", ("one.+four.+two.+three.+zero",)), + ("priority+,start-", ("zero.+three.+two.+one.+four",)), + ("priority+,start+", ("zero.+three.+two.+one.+four",)), + ("priority-,due-", ("four.+one.+two.+three.+zero",)), + ("priority-,due+", ("one.+four.+two.+three.+zero",)), + ("priority+,due-", ("zero.+three.+two.+four.+one",)), + ("priority+,due+", ("zero.+three.+two.+one.+four",)), + ("priority-,description-", ("one.+four.+two.+three.+zero",)), + ("priority-,description+", ("four.+one.+two.+three.+zero",)), + ("priority+,description-", ("zero.+three.+two.+one.+four",)), + ("priority+,description+", ("zero.+three.+two.+four.+one",)), + ("project-,priority-", ("four.+three.+two.+one.+zero",)), + ("project-,priority+", ("three.+four.+two.+one.+zero",)), + ("project+,priority-", ("zero.+one.+two.+four.+three",)), + ("project+,priority+", ("zero.+one.+two.+three.+four",)), + ("project-,start-", ("three.+four.+two.+one.+zero",)), + ("project-,start+", ("(?:four.+three|three.+four).+two.+one.+zero",)), + ("project+,start-", ("zero.+one.+two.+three.+four",)), + ("project+,start+", ("zero.+one.+two.+(?:four.+three|three.+four)",)), + ("project-,due-", ("three.+four.+two.+one.+zero",)), + ("project-,due+", ("four.+three.+two.+one.+zero",)), + ("project+,due-", ("zero.+one.+two.+three.+four",)), + ("project+,due+", ("zero.+one.+two.+four.+three",)), + ("project-,description-", ("three.+four.+two.+one.+zero",)), + ("project-,description+", ("four.+three.+two.+one.+zero",)), + ("project+,description-", ("zero.+one.+two.+three.+four",)), + ("project+,description+", ("zero.+one.+two.+four.+three",)), + ("start-,priority-", ("one.+four.+two.+three.+zero",)), + ("start-,priority+", ("one.+zero.+three.+two.+four",)), + ("start+,priority-", ("one.+four.+two.+three.+zero",)), + ("start+,priority+", ("one.+zero.+three.+two.+four",)), + ("start-,project-", ("one.+(?:three.+four|four.+three).+two.+zero",)), + ("start-,project+", ("one.+zero.+two.+(?:three.+four|four.+three)",)), + ("start+,project-", ("one.+(?:three.+four|four.+three).+two.+zero",)), + ("start+,project+", ("one.+zero.+two.+(?:three.+four|four.+three)",)), + ("start-,due-", ("one.+three.+(?:four.+two|two.+four).+zero",)), + ("start-,due+", ("one.+(?:four.+two|two.+four).+three.+zero",)), + ("start+,due-", ("one.+three.+(?:four.+two|two.+four).+zero",)), + ("start+,due+", ("one.+(?:four.+two|two.+four).+three.+zero",)), + ("start-,description-", ("one.+zero.+two.+three.+four",)), + ("start-,description+", ("one.+four.+three.+two.+zero",)), + ("start+,description-", ("one.+zero.+two.+three.+four",)), + ("start+,description+", ("one.+four.+three.+two.+zero",)), + ("due-,priority-", ("three.+four.+two.+one.+zero",)), + ("due-,priority+", ("three.+two.+four.+one.+zero",)), + ("due+,priority-", ("one.+four.+two.+three.+zero",)), + ("due+,priority+", ("one.+two.+four.+three.+zero",)), + ("due-,project-", ("three.+four.+two.+one.+zero",)), + ("due-,project+", ("three.+two.+four.+one.+zero",)), + ("due+,project-", ("one.+four.+two.+three.+zero",)), + ("due+,project+", ("one.+two.+four.+three.+zero",)), + ("due-,start-", ("three.+(?:four.+two|two.+four).+one.+zero",)), + ("due-,start+", ("three.+(?:four.+two|two.+four).+one.+zero",)), + ("due+,start-", ("one.+(?:four.+two|two.+four).+three.+zero",)), + ("due+,start+", ("one.+(?:four.+two|two.+four).+three.+zero",)), + ("due-,description-", ("three.+two.+four.+one.+zero",)), + ("due-,description+", ("three.+four.+two.+one.+zero",)), + ("due+,description-", ("one.+two.+four.+three.+zero",)), + ("due+,description+", ("one.+four.+two.+three.+zero",)), + ("description-,priority-", ("zero.+two.+three.+one.+four",)), + ("description-,priority+", ("zero.+two.+three.+one.+four",)), + ("description+,priority-", ("four.+one.+three.+two.+zero",)), + ("description+,priority+", ("four.+one.+three.+two.+zero",)), + ("description-,project-", ("zero.+two.+three.+one.+four",)), + ("description-,project+", ("zero.+two.+three.+one.+four",)), + ("description+,project-", ("four.+one.+three.+two.+zero",)), + ("description+,project+", ("four.+one.+three.+two.+zero",)), + ("description-,start-", ("zero.+two.+three.+one.+four",)), + ("description-,start+", ("zero.+two.+three.+one.+four",)), + ("description+,start-", ("four.+one.+three.+two.+zero",)), + ("description+,start+", ("four.+one.+three.+two.+zero",)), + ("description-,due-", ("zero.+two.+three.+one.+four",)), + ("description-,due+", ("zero.+two.+three.+one.+four",)), + ("description+,due-", ("four.+one.+three.+two.+zero",)), + ("description+,due+", ("four.+one.+three.+two.+zero",)), # Four sort columns. - ('start+,project+,due+,priority+', ('one.+zero.+two.+four.+three',)), - ('project+,due+,priority+,start+', ('zero.+one.+two.+four.+three',)), + ("start+,project+,due+,priority+", ("one.+zero.+two.+four.+three",)), + ("project+,due+,priority+,start+", ("zero.+one.+two.+four.+three",)), ) @@ -243,8 +239,8 @@ class TestBug438(TestCase): ("entry-", ("one newer.+one older",)), ("start+", ("two older.+two newer",)), ("start-", ("two newer.+two older",)), - ("end+", ("three older.+three newer",)), - ("end-", ("three newer.+three older",)), + ("end+", ("three older.+three newer",)), + ("end-", ("three newer.+three older",)), } @@ -258,13 +254,17 @@ class TestSortNone(TestCase): self.t("add two") self.t("add three") code, out, err = self.t("_get 1.uuid 2.uuid 3.uuid") - uuid1, uuid2, uuid3 = out.strip().split(' ') - code, out, err = self.t("%s %s %s list rc.report.list.sort:none rc.report.list.columns:id,description rc.report.list.labels:id,desc" % (uuid2, uuid3, uuid1)) - self.assertRegex(out, ' 2 two\n 3 three\n 1 one') + uuid1, uuid2, uuid3 = out.strip().split(" ") + code, out, err = self.t( + "%s %s %s list rc.report.list.sort:none rc.report.list.columns:id,description rc.report.list.labels:id,desc" + % (uuid2, uuid3, uuid1) + ) + self.assertRegex(out, " 2 two\n 3 three\n 1 one") if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/special.test.py b/test/special.test.py index d0dab40dc..a1ed28130 100755 --- a/test/special.test.py +++ b/test/special.test.py @@ -28,24 +28,26 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) from basetest import Task, TestCase + class TestSpecialTags(TestCase): @classmethod def setUpClass(cls): """Executed once before any test in the class""" cls.t = Task() cls.t.config("color.keyword.red", "red") - cls.t.config("color.alternate", "") - cls.t.config("color.tagged", "") - cls.t.config("color.pri.H", "") - cls.t.config("color.completed", "") - cls.t.config("nag", "NAG") - cls.t.config("color", "1") - cls.t.config("_forcecolor", "1") + cls.t.config("color.alternate", "") + cls.t.config("color.tagged", "") + cls.t.config("color.pri.H", "") + cls.t.config("color.completed", "") + cls.t.config("nag", "NAG") + cls.t.config("color", "1") + cls.t.config("_forcecolor", "1") def test_nocolor(self): self.t("add should have no red +nocolor priority:H") @@ -63,6 +65,7 @@ class TestSpecialTags(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/start.test.py b/test/start.test.py index e3a1db57b..c87b58f36 100755 --- a/test/start.test.py +++ b/test/start.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -81,9 +82,9 @@ class TestStart(TestCase): def test_journal_annotations(self): """Verify journal start/stop annotations are used""" - self.t.config("journal.time", "1") + self.t.config("journal.time", "1") self.t.config("journal.time.start.annotation", "Nu kör vi") - self.t.config("journal.time.stop.annotation", "Nu stannar vi") + self.t.config("journal.time.stop.annotation", "Nu stannar vi") self.t("add one") self.t("1 start") @@ -97,7 +98,7 @@ class TestStart(TestCase): def test_start_remove_end(self): """Verify that starting a task removes end timestamp""" self.t("add one") - uuid = self.t('_get 1.uuid')[1].strip() + uuid = self.t("_get 1.uuid")[1].strip() self.t("1 done") task = self.t.export()[0] @@ -129,7 +130,7 @@ class TestActiveTaskHandling(TestCase): def test_start_nothing(self): """Verify error message when no tasks are specified""" - code, out, err = self.t.runError ("999 start") + code, out, err = self.t.runError("999 start") self.assertIn("No tasks specified.", err) def test_start_started(self): @@ -160,6 +161,7 @@ class TestFeature608(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/stats.test.py b/test/stats.test.py index 54d5da70b..1d2f32e9c 100755 --- a/test/stats.test.py +++ b/test/stats.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -58,6 +59,7 @@ class TestStatisticsCommand(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/substitute.test.py b/test/substitute.test.py index 475d1eb5d..845076b25 100755 --- a/test/substitute.test.py +++ b/test/substitute.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -107,6 +108,7 @@ class TestBug441(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/sugar.test.py b/test/sugar.test.py index 326ae4f03..742138593 100755 --- a/test/sugar.test.py +++ b/test/sugar.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -38,9 +39,9 @@ class TestSugar(TestCase): def setUp(self): """Executed before each test in the class""" self.t = Task() - self.t('add one') - self.t('add two') - self.t('add three') + self.t("add one") + self.t("add two") + self.t("add three") def test_empty_conjunction(self): """Test syntax that mathematicians find sane and expected""" @@ -70,6 +71,7 @@ class TestSugar(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/summary.test.py b/test/summary.test.py index d83666439..8464aa51a 100755 --- a/test/summary.test.py +++ b/test/summary.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -72,9 +73,7 @@ class TestBug1904(TestCase): self.t("add pro:a.b test2") def validate_order(self, out): - order = ("a-b", - "a", - " b") + order = ("a-b", "a", " b") lines = out.splitlines(True) # position where project names start on the lines list @@ -85,8 +84,10 @@ class TestBug1904(TestCase): self.assertTrue( lines[pos].startswith(proj), - msg=("Project '{0}' is not in line #{1} or has an unexpected " - "indentation.{2}".format(proj, pos, out)) + msg=( + "Project '{0}' is not in line #{1} or has an unexpected " + "indentation.{2}".format(proj, pos, out) + ), ) def test_project_eval(self): @@ -98,6 +99,7 @@ class TestBug1904(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/t.test.cpp b/test/t.test.cpp index e0e35c4c0..d56015263 100644 --- a/test/t.test.cpp +++ b/test/t.test.cpp @@ -27,90 +27,89 @@ #include // cmake.h include header must come first -#include #include +#include #include //////////////////////////////////////////////////////////////////////////////// -int main (int, char**) -{ - UnitTest test (48); +int main(int, char**) { + UnitTest test(48); Context context; Context::setContext(&context); // Ensure environment has no influence. - unsetenv ("TASKDATA"); - unsetenv ("TASKRC"); + unsetenv("TASKDATA"); + unsetenv("TASKRC"); - test.is ((int)Task::textToStatus ("pending"), (int)Task::pending, "textToStatus pending"); - test.is ((int)Task::textToStatus ("completed"), (int)Task::completed, "textToStatus completed"); - test.is ((int)Task::textToStatus ("deleted"), (int)Task::deleted, "textToStatus deleted"); - test.is ((int)Task::textToStatus ("recurring"), (int)Task::recurring, "textToStatus recurring"); + test.is((int)Task::textToStatus("pending"), (int)Task::pending, "textToStatus pending"); + test.is((int)Task::textToStatus("completed"), (int)Task::completed, "textToStatus completed"); + test.is((int)Task::textToStatus("deleted"), (int)Task::deleted, "textToStatus deleted"); + test.is((int)Task::textToStatus("recurring"), (int)Task::recurring, "textToStatus recurring"); - test.is (Task::statusToText (Task::pending), "pending", "statusToText pending"); - test.is (Task::statusToText (Task::completed), "completed", "statusToText completed"); - test.is (Task::statusToText (Task::deleted), "deleted", "statusToText deleted"); - test.is (Task::statusToText (Task::recurring), "recurring", "statusToText recurring"); + test.is(Task::statusToText(Task::pending), "pending", "statusToText pending"); + test.is(Task::statusToText(Task::completed), "completed", "statusToText completed"); + test.is(Task::statusToText(Task::deleted), "deleted", "statusToText deleted"); + test.is(Task::statusToText(Task::recurring), "recurring", "statusToText recurring"); -/* + /* -TODO Task::composeCSV -TODO Task::composeYAML -TODO Task::id -TODO Task::*Status -TODO Task::*Tag* -TODO Task::*Annotation* + TODO Task::composeCSV + TODO Task::composeYAML + TODO Task::id + TODO Task::*Status + TODO Task::*Tag* + TODO Task::*Annotation* -TODO Task::addDependency -TODO Task::addDependency -TODO Task::removeDependency -TODO Task::removeDependency -TODO Task::getDependencies -TODO Task::getDependencies + TODO Task::addDependency + TODO Task::addDependency + TODO Task::removeDependency + TODO Task::removeDependency + TODO Task::getDependencies + TODO Task::getDependencies -TODO Task::urgency + TODO Task::urgency -TODO Task::encode -TODO Task::decode + TODO Task::encode + TODO Task::decode -*/ + */ // Task::operator== - Task left ("{\"one\":\"1\", \"two\":\"2\", \"three\":\"3\"}"); - Task right (left); - test.ok (left == right, "left == right -> true"); - left.set ("one", "1.0"); - test.notok (left == right, "left == right -> false"); + Task left("{\"one\":\"1\", \"two\":\"2\", \"three\":\"3\"}"); + Task right(left); + test.ok(left == right, "left == right -> true"); + left.set("one", "1.0"); + test.notok(left == right, "left == right -> false"); //////////////////////////////////////////////////////////////////////////////// Task task; // Task::set task = Task(); - task.set ("name", "value"); - test.is (task.composeJSON (), "{\"name\":\"value\"}", "Task::set"); + task.set("name", "value"); + test.is(task.composeJSON(), "{\"name\":\"value\"}", "Task::set"); // Task::has - test.ok (task.has ("name"), "Task::has"); - test.notok (task.has ("woof"), "Task::has not"); + test.ok(task.has("name"), "Task::has"); + test.notok(task.has("woof"), "Task::has not"); // Task::get_int - task.set ("one", 1); - test.is (task.composeJSON (), R"({"name":"value","one":"1"})", "Task::set"); - test.is (task.get_int ("one"), 1, "Task::get_int"); + task.set("one", 1); + test.is(task.composeJSON(), R"({"name":"value","one":"1"})", "Task::set"); + test.is(task.get_int("one"), 1, "Task::get_int"); // Task::get_ulong - task.set ("two", "4294967295"); - test.is (task.composeJSON (), R"({"name":"value","one":"1","two":"4294967295"})", "Task::set"); - test.is ((size_t)task.get_ulong ("two"), (size_t)4294967295UL, "Task::get_ulong"); + task.set("two", "4294967295"); + test.is(task.composeJSON(), R"({"name":"value","one":"1","two":"4294967295"})", "Task::set"); + test.is((size_t)task.get_ulong("two"), (size_t)4294967295UL, "Task::get_ulong"); // Task::remove - task.remove ("one"); - task.remove ("two"); - test.is (task.composeJSON (), "{\"name\":\"value\"}", "Task::remove"); + task.remove("one"); + task.remove("two"); + test.is(task.composeJSON(), "{\"name\":\"value\"}", "Task::remove"); // Task::all - test.is (task.all ().size (), (size_t)1, "Task::all size"); + test.is(task.all().size(), (size_t)1, "Task::all size"); //////////////////////////////////////////////////////////////////////////////// @@ -120,34 +119,51 @@ TODO Task::decode Task::attributes["uuid"] = "string"; bool good = true; - try {Task t4 ("{}");} - catch (const std::string& e){test.diag (e); good = false;} - test.ok (good, "Task::Task ('{}')"); + try { + Task t4("{}"); + } catch (const std::string& e) { + test.diag(e); + good = false; + } + test.ok(good, "Task::Task ('{}')"); good = true; - try {Task t5 (R"({"uuid":"00000000-0000-0000-000000000001","description":"foo","entry":"1234567890"})");} - catch (const std::string& e){test.diag (e); good = false;} - test.ok (good, "Task::Task ('{}')"); + try { + Task t5( + R"({"uuid":"00000000-0000-0000-000000000001","description":"foo","entry":"1234567890"})"); + } catch (const std::string& e) { + test.diag(e); + good = false; + } + test.ok(good, "Task::Task ('{}')"); // Verify tag handling is correct Task t6; - t6.set ("entry", "20130602T224000Z"); - t6.set ("description", "DESC"); - t6.addTag ("tag1"); - test.is (t6.composeJSON (), R"({"description":"DESC","entry":"20130602T224000Z","tags":["tag1"]})", "JSON good"); + t6.set("entry", "20130602T224000Z"); + t6.set("description", "DESC"); + t6.addTag("tag1"); + test.is(t6.composeJSON(), R"({"description":"DESC","entry":"20130602T224000Z","tags":["tag1"]})", + "JSON good"); - t6.addTag ("tag2"); - test.is (t6.composeJSON (), R"({"description":"DESC","entry":"20130602T224000Z","tags":["tag1","tag2"]})", "JSON good"); + t6.addTag("tag2"); + test.is(t6.composeJSON(), + R"({"description":"DESC","entry":"20130602T224000Z","tags":["tag1","tag2"]})", + "JSON good"); good = true; Task t7; - try {t7 = Task (R"({"description":"DESC","entry":"20130602T224000Z","tags":["tag1","tag2"]})");} - catch (const std::string& e){test.diag (e); good = false;} - test.ok (good, "Task::Task ('{two tags}')"); - test.is (t7.composeJSON (), R"({"description":"DESC","entry":"20130602T224000Z","tags":["tag1","tag2"]})", "JSON good"); + try { + t7 = Task(R"({"description":"DESC","entry":"20130602T224000Z","tags":["tag1","tag2"]})"); + } catch (const std::string& e) { + test.diag(e); + good = false; + } + test.ok(good, "Task::Task ('{two tags}')"); + test.is(t7.composeJSON(), + R"({"description":"DESC","entry":"20130602T224000Z","tags":["tag1","tag2"]})", + "JSON good"); return 0; } //////////////////////////////////////////////////////////////////////////////// - diff --git a/test/tag.test.py b/test/tag.test.py index ba517d39e..32e4e0163 100755 --- a/test/tag.test.py +++ b/test/tag.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -41,15 +42,13 @@ class TestTags(TestCase): self.t = Task() def split_tags(self, tags): - return sorted(tags.strip().split(',')) + return sorted(tags.strip().split(",")) def test_tag_manipulation(self): """Test addition and removal of tags""" self.t("add +one This +two is a test +three") code, out, err = self.t("_get 1.tags") - self.assertEqual( - sorted(["one", "two", "three"]), - self.split_tags(out)) + self.assertEqual(sorted(["one", "two", "three"]), self.split_tags(out)) # Remove tags. self.t("1 modify -three -two -one") @@ -59,9 +58,7 @@ class TestTags(TestCase): # Add tags. self.t("1 modify +four +five +six") code, out, err = self.t("_get 1.tags") - self.assertEqual( - sorted(["four", "five", "six"]), - self.split_tags(out)) + self.assertEqual(sorted(["four", "five", "six"]), self.split_tags(out)) # Remove tags. self.t("1 modify -four -five -six") @@ -81,9 +78,7 @@ class TestTags(TestCase): """2655: Test bulk removal of tags""" self.t("add +one This +two is a test +three") code, out, err = self.t("_get 1.tags") - self.assertEqual( - sorted(["one", "two", "three"]), - self.split_tags(out)) + self.assertEqual(sorted(["one", "two", "three"]), self.split_tags(out)) # Remove all tags in bulk self.t("1 modify tags:") @@ -432,7 +427,7 @@ class TestVirtualTagUDA(TestCase): def setUp(self): """Executed before each test in the class""" self.t = Task() - self.t.config("uda.animal.type", "string") + self.t.config("uda.animal.type", "string") self.t.config("uda.animal.label", "Animal") self.t("add one animal:donkey") self.t("add two") @@ -448,7 +443,9 @@ class TestVirtualTagORPHAN(TestCase): def setUp(self): """Executed before each test in the class""" self.t = Task() - self.t("add one rc.uda.animal.type:string rc.uda.animal.label:Animal animal:donkey") + self.t( + "add one rc.uda.animal.type:string rc.uda.animal.label:Animal animal:donkey" + ) self.t("add two") def test_virtual_tag_ORPHAN(self): @@ -473,13 +470,13 @@ class Test285(TestCase): # due:1month - - - - - - - ? # due:1year - - - - - - - - - cls.t('add due_last_week due:-1week') - cls.t('add due_yesterday due:-1day') - cls.t('add due_earlier_today due:today') - cls.t('add due_later_today due:tomorrow') - cls.t('add due_three_days due:3days') - cls.t('add due_next_month due:1month') - cls.t('add due_next_year due:1year') + cls.t("add due_last_week due:-1week") + cls.t("add due_yesterday due:-1day") + cls.t("add due_earlier_today due:today") + cls.t("add due_later_today due:tomorrow") + cls.t("add due_three_days due:3days") + cls.t("add due_next_month due:1month") + cls.t("add due_next_year due:1year") def test_overdue(self): """285: +OVERDUE""" @@ -537,8 +534,8 @@ class TestListAllTags(TestCase): def test_list_all_tags(self): """Verify the 'tags' command obeys 'rc.list.all.tags' - Create a data set of two tasks, with unique tags, one - pending, one completed. + Create a data set of two tasks, with unique tags, one + pending, one completed. """ self.t("add +t1 one") self.t("add +t2 two") @@ -570,6 +567,7 @@ class TestBug1700(TestCase): self.assertNotIn("tag1", out) self.assertIn("tag2,tag3", out) + class TestBug818(TestCase): def setUp(self): """Executed before each test in the class""" @@ -599,6 +597,7 @@ class TestBug818(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/taskrc.test.py b/test/taskrc.test.py index 4f88a1632..044681881 100755 --- a/test/taskrc.test.py +++ b/test/taskrc.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -48,6 +49,7 @@ class TestTaskrc(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/tc.test.cpp b/test/tc.test.cpp index 724105404..e3351e101 100644 --- a/test/tc.test.cpp +++ b/test/tc.test.cpp @@ -27,19 +27,20 @@ #include // cmake.h include header must come first -#include #include #include -#include "test.h" + +#include + #include "tc/Replica.h" -#include "tc/WorkingSet.h" #include "tc/Task.h" +#include "tc/WorkingSet.h" #include "tc/util.h" +#include "test.h" //////////////////////////////////////////////////////////////////////////////// -int main (int, char**) -{ - UnitTest t (23); +int main(int, char**) { + UnitTest t(23); // This function contains unit tests for the various bits of the wrappers for // taskchampion-lib (that is, for `src/tc/*.cpp`). @@ -47,69 +48,69 @@ int main (int, char**) //// util { - auto s1 = std::string ("a\0string!"); - auto stc = tc::string2tc (s1); - auto s2 = tc::tc2string (stc); - t.is (s1, s2, "round-trip to tc string and back (containing an embedded NUL)"); + auto s1 = std::string("a\0string!"); + auto stc = tc::string2tc(s1); + auto s2 = tc::tc2string(stc); + t.is(s1, s2, "round-trip to tc string and back (containing an embedded NUL)"); } { - auto s1 = std::string ("62123ec9-c443-4f7e-919a-35362a8bef8d"); - auto tcuuid = tc::uuid2tc (s1); - auto s2 = tc::tc2uuid (tcuuid); + auto s1 = std::string("62123ec9-c443-4f7e-919a-35362a8bef8d"); + auto tcuuid = tc::uuid2tc(s1); + auto s2 = tc::tc2uuid(tcuuid); t.is(s1, s2, "round-trip to TCUuid and back"); } //// Replica - auto rep = tc::Replica (); - t.pass ("replica constructed"); + auto rep = tc::Replica(); + t.pass("replica constructed"); auto maybe_task = rep.get_task("24478a28-4609-4257-bc19-44ec51391431"); t.notok(maybe_task.has_value(), "task with fixed uuid does not exist"); - auto task = rep.new_task (tc::Status::Pending, "a test"); - t.pass ("new task constructed"); - t.is (task.get_description (), std::string ("a test"), "task description round-trip"); - t.is (task.get_status (), tc::Status::Pending, "task status round-trip"); + auto task = rep.new_task(tc::Status::Pending, "a test"); + t.pass("new task constructed"); + t.is(task.get_description(), std::string("a test"), "task description round-trip"); + t.is(task.get_status(), tc::Status::Pending, "task status round-trip"); auto uuid = task.get_uuid(); - auto maybe_task2 = rep.get_task (uuid); + auto maybe_task2 = rep.get_task(uuid); t.ok(maybe_task2.has_value(), "task lookup by uuid finds task"); - t.is ((*maybe_task2).get_description (), std::string ("a test"), "task description round-trip"); + t.is((*maybe_task2).get_description(), std::string("a test"), "task description round-trip"); - rep.rebuild_working_set (true); - t.pass ("rebuild_working_set"); + rep.rebuild_working_set(true); + t.pass("rebuild_working_set"); - auto tasks = rep.all_tasks (); - t.is ((int)tasks.size(), 1, "all_tasks returns one task"); + auto tasks = rep.all_tasks(); + t.is((int)tasks.size(), 1, "all_tasks returns one task"); //// Task task = std::move(tasks[0]); - t.is (task.get_uuid(), uuid, "returned task has correct uuid"); - t.is (task.get_status(), tc::Status::Pending, "returned task is pending"); - auto map = task.get_taskmap (); - t.is (map["description"], "a test", "task description in taskmap"); - t.is (task.get_description(), "a test", "returned task has correct description"); - t.is (task.is_waiting(), false, "task is not waiting"); - t.is (task.is_active(), false, "task is not active"); + t.is(task.get_uuid(), uuid, "returned task has correct uuid"); + t.is(task.get_status(), tc::Status::Pending, "returned task is pending"); + auto map = task.get_taskmap(); + t.is(map["description"], "a test", "task description in taskmap"); + t.is(task.get_description(), "a test", "returned task has correct description"); + t.is(task.is_waiting(), false, "task is not waiting"); + t.is(task.is_active(), false, "task is not active"); //// WorkingSet - auto ws = rep.working_set (); + auto ws = rep.working_set(); - t.is (ws.len (), (size_t)1, "WorkingSet::len"); - t.is (ws.largest_index (), (size_t)1, "WorkingSet::largest_index"); - t.is (ws.by_index (1).value(), uuid, "WorkingSet::by_index"); - t.is (ws.by_index (2).has_value(), false, "WorkingSet::by_index for unknown index"); - t.is (ws.by_uuid (uuid).value (), (size_t)1, "WorkingSet::by_uuid"); - t.is (ws.by_uuid ("3e18a306-e3a8-4a53-a85c-fa7c057759a2").has_value (), false, "WorkingSet::by_uuid for unknown uuid"); + t.is(ws.len(), (size_t)1, "WorkingSet::len"); + t.is(ws.largest_index(), (size_t)1, "WorkingSet::largest_index"); + t.is(ws.by_index(1).value(), uuid, "WorkingSet::by_index"); + t.is(ws.by_index(2).has_value(), false, "WorkingSet::by_index for unknown index"); + t.is(ws.by_uuid(uuid).value(), (size_t)1, "WorkingSet::by_uuid"); + t.is(ws.by_uuid("3e18a306-e3a8-4a53-a85c-fa7c057759a2").has_value(), false, + "WorkingSet::by_uuid for unknown uuid"); return 0; } //////////////////////////////////////////////////////////////////////////////// - diff --git a/test/tdb2.test.cpp b/test/tdb2.test.cpp index 03b1d9f84..e9a0b1508 100644 --- a/test/tdb2.test.cpp +++ b/test/tdb2.test.cpp @@ -27,114 +27,108 @@ #include // cmake.h include header must come first -#include -#include -#include #include +#include #include +#include + +#include Context context; -void cleardb () -{ - // Remove any residual test files. - rmdir ("./extensions"); - unlink ("./taskchampion.sqlite3"); +void cleardb() { + // Remove any residual test files. + rmdir("./extensions"); + unlink("./taskchampion.sqlite3"); } //////////////////////////////////////////////////////////////////////////////// -int main (int, char**) -{ - UnitTest t (12); +int main(int, char**) { + UnitTest t(12); Context context; Context::setContext(&context); // Ensure environment has no influence. - unsetenv ("TASKDATA"); - unsetenv ("TASKRC"); + unsetenv("TASKDATA"); + unsetenv("TASKRC"); - try - { - cleardb (); + try { + cleardb(); // Set the context to allow GC. - context.config.set ("gc", 1); - context.config.set ("debug", 1); + context.config.set("gc", 1); + context.config.set("debug", 1); - context.tdb2.open_replica (".", true); + context.tdb2.open_replica(".", true); // Try reading an empty database. - std::vector pending = context.tdb2.pending_tasks (); - std::vector completed = context.tdb2.completed_tasks (); - int num_reverts_possible = context.tdb2.num_reverts_possible (); - int num_local_changes = context.tdb2.num_local_changes (); + std::vector pending = context.tdb2.pending_tasks(); + std::vector completed = context.tdb2.completed_tasks(); + int num_reverts_possible = context.tdb2.num_reverts_possible(); + int num_local_changes = context.tdb2.num_local_changes(); - t.is ((int) pending.size (), 0, "TDB2 Read empty pending"); - t.is ((int) completed.size (), 0, "TDB2 Read empty completed"); - t.is ((int) num_reverts_possible, 0, "TDB2 Read empty undo"); - t.is ((int) num_local_changes, 0, "TDB2 Read empty backlog"); + t.is((int)pending.size(), 0, "TDB2 Read empty pending"); + t.is((int)completed.size(), 0, "TDB2 Read empty completed"); + t.is((int)num_reverts_possible, 0, "TDB2 Read empty undo"); + t.is((int)num_local_changes, 0, "TDB2 Read empty backlog"); // Add a task. - Task task (R"([description:"description" name:"value"])"); - context.tdb2.add (task); + Task task(R"([description:"description" name:"value"])"); + context.tdb2.add(task); - pending = context.tdb2.pending_tasks (); - completed = context.tdb2.completed_tasks (); - num_reverts_possible = context.tdb2.num_reverts_possible (); - num_local_changes = context.tdb2.num_local_changes (); + pending = context.tdb2.pending_tasks(); + completed = context.tdb2.completed_tasks(); + num_reverts_possible = context.tdb2.num_reverts_possible(); + num_local_changes = context.tdb2.num_local_changes(); - t.is ((int) pending.size (), 1, "TDB2 after add, 1 pending task"); - t.is ((int) completed.size (), 0, "TDB2 after add, 0 completed tasks"); - t.is ((int) num_reverts_possible, 1, "TDB2 after add, 1 revert possible"); - t.is ((int) num_local_changes, 6, "TDB2 after add, 6 local changes"); + t.is((int)pending.size(), 1, "TDB2 after add, 1 pending task"); + t.is((int)completed.size(), 0, "TDB2 after add, 0 completed tasks"); + t.is((int)num_reverts_possible, 1, "TDB2 after add, 1 revert possible"); + t.is((int)num_local_changes, 6, "TDB2 after add, 6 local changes"); - task.set ("description", "This is a test"); - context.tdb2.modify (task); + task.set("description", "This is a test"); + context.tdb2.modify(task); - pending = context.tdb2.pending_tasks (); - completed = context.tdb2.completed_tasks (); - num_reverts_possible = context.tdb2.num_reverts_possible (); - num_local_changes = context.tdb2.num_local_changes (); + pending = context.tdb2.pending_tasks(); + completed = context.tdb2.completed_tasks(); + num_reverts_possible = context.tdb2.num_reverts_possible(); + num_local_changes = context.tdb2.num_local_changes(); - t.is ((int) pending.size (), 1, "TDB2 after set, 1 pending task"); - t.is ((int) completed.size (), 0, "TDB2 after set, 0 completed tasks"); - t.is ((int) num_reverts_possible, 1, "TDB2 after set, 1 revert possible"); + t.is((int)pending.size(), 1, "TDB2 after set, 1 pending task"); + t.is((int)completed.size(), 0, "TDB2 after set, 0 completed tasks"); + t.is((int)num_reverts_possible, 1, "TDB2 after set, 1 revert possible"); // At this point, there may be 7 or 8 local changes, depending on whether // the `modified` property changed between the `add` and `modify` // invocation. That only happens if the clock ticks over to the next second // between those invocations. - t.ok (num_local_changes == 7 || num_local_changes == 8, - "TDB2 after set, 7 or 8 local changes"); + t.ok(num_local_changes == 7 || num_local_changes == 8, "TDB2 after set, 7 or 8 local changes"); // Reset for reuse. - cleardb (); - context.tdb2.open_replica (".", true); + cleardb(); + context.tdb2.open_replica(".", true); // TODO complete a task // TODO gc } - catch (const std::string& error) - { - t.diag (error); + catch (const std::string& error) { + t.diag(error); return -1; } - catch (...) - { - t.diag ("Unknown error."); + catch (...) { + t.diag("Unknown error."); return -2; } - rmdir ("./extensions"); - unlink ("./pending.data"); - unlink ("./completed.data"); - unlink ("./undo.data"); - unlink ("./backlog.data"); + rmdir("./extensions"); + unlink("./pending.data"); + unlink("./completed.data"); + unlink("./undo.data"); + unlink("./backlog.data"); return 0; } //////////////////////////////////////////////////////////////////////////////// - diff --git a/test/template.test.py b/test/template.test.py index 303795c90..ed6450d59 100755 --- a/test/template.test.py +++ b/test/template.test.py @@ -29,6 +29,7 @@ import sys import os import unittest from datetime import datetime + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -53,6 +54,7 @@ from basetest import Task, TestCase # self.assertNotRegex(t, r) # self.tap("") + class TestBugNumber(TestCase): @classmethod def setUpClass(cls): @@ -80,16 +82,16 @@ class TestBugNumber(TestCase): def test_faketime(self): """Running tests using libfaketime - WARNING: - faketime version 0.9.6 and later correctly propagates non-zero - exit codes. Please don't combine faketime tests and - self.t.runError(). + WARNING: + faketime version 0.9.6 and later correctly propagates non-zero + exit codes. Please don't combine faketime tests and + self.t.runError(). - https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=750721 + https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=750721 """ self.t.faketime("-2y") - command = ("add Testing") + command = "add Testing" self.t(command) # Remove FAKETIME settings @@ -188,12 +190,12 @@ sys.exit(0) self.assertIn("/Hello/Greetings/", logs["calls"][0]["args"]) # Some message output from the hook - self.assertEqual(logs["output"]["msgs"][0], - "Hello from the template hook") + self.assertEqual(logs["output"]["msgs"][0], "Hello from the template hook") # This is what taskwarrior received - self.assertEqual(logs["output"]["json"][0]["description"], - "This is an example modify hook") + self.assertEqual( + logs["output"]["json"][0]["description"], "This is an example modify hook" + ) def test_onmodify_bad_builtin_with_log(self): """Testing a builtin hook and keeping track of its input/output @@ -216,16 +218,17 @@ sys.exit(0) hook.assertExitcode(1) # Some message output from the hook - self.assertEqual(logs["output"]["msgs"][0], - "Hello from the template hook") + self.assertEqual(logs["output"]["msgs"][0], "Hello from the template hook") # This is what taskwarrior would have used if hook finished cleanly - self.assertEqual(logs["output"]["json"][0]["description"], - "This is an example modify hook") + self.assertEqual( + logs["output"]["json"][0]["description"], "This is an example modify hook" + ) if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/test.cpp b/test/test.cpp index 7f092af90..32f62c4b7 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -24,75 +24,46 @@ // //////////////////////////////////////////////////////////////////////////////// -#include -#include -#include -#include -#include #include +#include #include +#include #include +#include + +#include +#include /////////////////////////////////////////////////////////////////////////////// -UnitTest::UnitTest () -: _planned (0) -, _counter (0) -, _passed (0) -, _failed (0) -, _skipped (0) -{ -} +UnitTest::UnitTest() : _planned(0), _counter(0), _passed(0), _failed(0), _skipped(0) {} /////////////////////////////////////////////////////////////////////////////// -UnitTest::UnitTest (int planned) -: _planned (planned) -, _counter (0) -, _passed (0) -, _failed (0) -, _skipped (0) -{ +UnitTest::UnitTest(int planned) + : _planned(planned), _counter(0), _passed(0), _failed(0), _skipped(0) { std::cout << "1.." << _planned << '\n'; } /////////////////////////////////////////////////////////////////////////////// -UnitTest::~UnitTest () -{ +UnitTest::~UnitTest() { float percentPassed = 0.0; if (_planned > 0) - percentPassed = (100.0 * _passed) / std::max (_planned, _passed + _failed + _skipped); + percentPassed = (100.0 * _passed) / std::max(_planned, _passed + _failed + _skipped); - if (_counter < _planned) - { - std::cout << "# Only " - << _counter - << " tests, out of a planned " - << _planned - << " were run.\n"; + if (_counter < _planned) { + std::cout << "# Only " << _counter << " tests, out of a planned " << _planned << " were run.\n"; _skipped += _planned - _counter; } else if (_counter > _planned) - std::cout << "# " - << _counter - << " tests were run, but only " - << _planned - << " were planned.\n"; + std::cout << "# " << _counter << " tests were run, but only " << _planned << " were planned.\n"; - std::cout << "# " - << _passed - << " passed, " - << _failed - << " failed, " - << _skipped - << " skipped. " - << std::setprecision (3) << percentPassed - << "% passed.\n"; - exit (_failed > 0); + std::cout << "# " << _passed << " passed, " << _failed << " failed, " << _skipped << " skipped. " + << std::setprecision(3) << percentPassed << "% passed.\n"; + exit(_failed > 0); } /////////////////////////////////////////////////////////////////////////////// -void UnitTest::plan (int planned) -{ +void UnitTest::plan(int planned) { _planned = planned; _counter = 0; _passed = 0; @@ -103,429 +74,225 @@ void UnitTest::plan (int planned) } /////////////////////////////////////////////////////////////////////////////// -void UnitTest::planMore (int extra) -{ +void UnitTest::planMore(int extra) { _planned += extra; std::cout << "1.." << _planned << '\n'; } /////////////////////////////////////////////////////////////////////////////// -void UnitTest::ok (bool expression, const std::string& name, bool expfail /* = false */) -{ +void UnitTest::ok(bool expression, const std::string& name, bool expfail /* = false */) { ++_counter; bool success = expression; - if (success and ! expfail) - { + if (success and !expfail) { ++_passed; - std::cout << green ("ok") - << " " - << _counter - << " - " - << name - << '\n'; - } - else - { - if (success == expfail) - ++_failed; - std::cout << red ("not ok") - << " " - << _counter - << " - " - << name - << (expfail ? (success ? " # FIXED" : " # TODO") : "") - << '\n'; + std::cout << green("ok") << " " << _counter << " - " << name << '\n'; + } else { + if (success == expfail) ++_failed; + std::cout << red("not ok") << " " << _counter << " - " << name + << (expfail ? (success ? " # FIXED" : " # TODO") : "") << '\n'; } } /////////////////////////////////////////////////////////////////////////////// -void UnitTest::notok (bool expression, const std::string& name, bool expfail /* = false */) -{ +void UnitTest::notok(bool expression, const std::string& name, bool expfail /* = false */) { ++_counter; bool success = not expression; - if (success and ! expfail) - { + if (success and !expfail) { ++_passed; - std::cout << green ("ok") - << " " - << _counter - << " - " - << name - << '\n'; - } - else - { - if (success == expfail) - ++_failed; - std::cout << red ("not ok") - << " " - << _counter - << " - " - << name - << (expfail ? (success ? " # FIXED" : " # TODO") : "") - << '\n'; + std::cout << green("ok") << " " << _counter << " - " << name << '\n'; + } else { + if (success == expfail) ++_failed; + std::cout << red("not ok") << " " << _counter << " - " << name + << (expfail ? (success ? " # FIXED" : " # TODO") : "") << '\n'; } } /////////////////////////////////////////////////////////////////////////////// -void UnitTest::is (bool actual, bool expected, const std::string& name, bool expfail /* = false */) -{ +void UnitTest::is(bool actual, bool expected, const std::string& name, bool expfail /* = false */) { ++_counter; bool success = (actual == expected); - if (success and ! expfail) - { + if (success and !expfail) { ++_passed; - std::cout << green ("ok") - << " " - << _counter - << " - " - << name - << '\n'; - } - else - { - if (success == expfail) - ++_failed; - std::cout << red ("not ok") - << " " - << _counter - << " - " - << name - << (expfail ? (success ? " # FIXED" : " # TODO") : "") - << "\n# expected: " - << expected - << "\n# got: " - << actual - << '\n'; + std::cout << green("ok") << " " << _counter << " - " << name << '\n'; + } else { + if (success == expfail) ++_failed; + std::cout << red("not ok") << " " << _counter << " - " << name + << (expfail ? (success ? " # FIXED" : " # TODO") : "") << "\n# expected: " << expected + << "\n# got: " << actual << '\n'; } } /////////////////////////////////////////////////////////////////////////////// -void UnitTest::is (size_t actual, size_t expected, const std::string& name, bool expfail /* = false */) -{ +void UnitTest::is(size_t actual, size_t expected, const std::string& name, + bool expfail /* = false */) { ++_counter; bool success = (actual == expected); - if (success and ! expfail) - { + if (success and !expfail) { ++_passed; - std::cout << green ("ok") - << " " - << _counter - << " - " - << name - << '\n'; - } - else - { - if (success == expfail) - ++_failed; - std::cout << red ("not ok") - << " " - << _counter - << " - " - << name - << (expfail ? (success ? " # FIXED" : " # TODO") : "") - << "\n# expected: " - << expected - << "\n# got: " - << actual - << '\n'; + std::cout << green("ok") << " " << _counter << " - " << name << '\n'; + } else { + if (success == expfail) ++_failed; + std::cout << red("not ok") << " " << _counter << " - " << name + << (expfail ? (success ? " # FIXED" : " # TODO") : "") << "\n# expected: " << expected + << "\n# got: " << actual << '\n'; } } /////////////////////////////////////////////////////////////////////////////// -void UnitTest::is (int actual, int expected, const std::string& name, bool expfail /* = false */) -{ +void UnitTest::is(int actual, int expected, const std::string& name, bool expfail /* = false */) { ++_counter; bool success = (actual == expected); - if (success and ! expfail) - { + if (success and !expfail) { ++_passed; - std::cout << green ("ok") - << " " - << _counter - << " - " - << name - << '\n'; - } - else - { - if (success == expfail) - ++_failed; - std::cout << red ("not ok") - << " " - << _counter - << " - " - << name - << (expfail ? (success ? " # FIXED" : " # TODO") : "") - << "\n# expected: " - << expected - << "\n# got: " - << actual - << '\n'; + std::cout << green("ok") << " " << _counter << " - " << name << '\n'; + } else { + if (success == expfail) ++_failed; + std::cout << red("not ok") << " " << _counter << " - " << name + << (expfail ? (success ? " # FIXED" : " # TODO") : "") << "\n# expected: " << expected + << "\n# got: " << actual << '\n'; } } /////////////////////////////////////////////////////////////////////////////// -void UnitTest::is (double actual, double expected, const std::string& name, bool expfail /* = false */) -{ +void UnitTest::is(double actual, double expected, const std::string& name, + bool expfail /* = false */) { ++_counter; bool success = (actual == expected); - if (success and ! expfail) - { + if (success and !expfail) { ++_passed; - std::cout << green ("ok") - << " " - << _counter - << " - " - << name - << '\n'; - } - else - { - if (success == expfail) - ++_failed; - std::cout << red ("not ok") - << " " - << _counter - << " - " - << name - << (expfail ? (success ? " # FIXED" : " # TODO") : "") - << "\n# expected: " - << expected - << "\n# got: " - << actual - << '\n'; + std::cout << green("ok") << " " << _counter << " - " << name << '\n'; + } else { + if (success == expfail) ++_failed; + std::cout << red("not ok") << " " << _counter << " - " << name + << (expfail ? (success ? " # FIXED" : " # TODO") : "") << "\n# expected: " << expected + << "\n# got: " << actual << '\n'; } } /////////////////////////////////////////////////////////////////////////////// -void UnitTest::is (double actual, double expected, double tolerance, const std::string& name, bool expfail /* = false */) -{ +void UnitTest::is(double actual, double expected, double tolerance, const std::string& name, + bool expfail /* = false */) { ++_counter; - bool success = (fabs (actual - expected) <= tolerance); + bool success = (fabs(actual - expected) <= tolerance); - if (success and ! expfail) - { + if (success and !expfail) { ++_passed; - std::cout << green ("ok") - << " " - << _counter - << " - " - << name - << '\n'; - } - else - { - if (success == expfail) - ++_failed; - std::cout << red ("not ok") - << " " - << _counter - << " - " - << name - << (expfail ? (success ? " # FIXED" : " # TODO") : "") - << "\n# expected: " - << expected - << "\n# got: " - << actual - << '\n'; + std::cout << green("ok") << " " << _counter << " - " << name << '\n'; + } else { + if (success == expfail) ++_failed; + std::cout << red("not ok") << " " << _counter << " - " << name + << (expfail ? (success ? " # FIXED" : " # TODO") : "") << "\n# expected: " << expected + << "\n# got: " << actual << '\n'; } } /////////////////////////////////////////////////////////////////////////////// -void UnitTest::is (unsigned char actual, unsigned char expected, const std::string& name, bool expfail /* = false */) -{ +void UnitTest::is(unsigned char actual, unsigned char expected, const std::string& name, + bool expfail /* = false */) { ++_counter; bool success = (actual == expected); - if (success and ! expfail) - { + if (success and !expfail) { ++_passed; - std::cout << green ("ok") - << " " - << _counter - << " - " - << name - << '\n'; - } - else - { - if (success == expfail) - ++_failed; - std::cout << red ("not ok") - << " " - << _counter - << " - " - << name - << (expfail ? (success ? " # FIXED" : " # TODO") : "") - << "\n# expected: " - << expected - << "\n# got: " - << actual - << '\n'; + std::cout << green("ok") << " " << _counter << " - " << name << '\n'; + } else { + if (success == expfail) ++_failed; + std::cout << red("not ok") << " " << _counter << " - " << name + << (expfail ? (success ? " # FIXED" : " # TODO") : "") << "\n# expected: " << expected + << "\n# got: " << actual << '\n'; } } /////////////////////////////////////////////////////////////////////////////// -void UnitTest::is ( - const std::string& actual, - const std::string& expected, - const std::string& name, - bool expfail /* = false */) -{ +void UnitTest::is(const std::string& actual, const std::string& expected, const std::string& name, + bool expfail /* = false */) { ++_counter; bool success = (actual == expected); - if (success and ! expfail) - { + if (success and !expfail) { ++_passed; - std::cout << green ("ok") - << " " - << _counter - << " - " - << name - << '\n'; - } - else - { - if (success == expfail) - ++_failed; - std::cout << red ("not ok") - << " " - << _counter - << " - " - << name - << (expfail ? (success ? " # FIXED" : " # TODO") : "") - << "\n# expected: '" - << expected - << "'" - << "\n# got: '" - << actual - << "'\n"; + std::cout << green("ok") << " " << _counter << " - " << name << '\n'; + } else { + if (success == expfail) ++_failed; + std::cout << red("not ok") << " " << _counter << " - " << name + << (expfail ? (success ? " # FIXED" : " # TODO") : "") << "\n# expected: '" + << expected << "'" + << "\n# got: '" << actual << "'\n"; } } /////////////////////////////////////////////////////////////////////////////// -void UnitTest::is ( - const char* actual, - const char* expected, - const std::string& name, - bool expfail /* = false */) -{ +void UnitTest::is(const char* actual, const char* expected, const std::string& name, + bool expfail /* = false */) { ++_counter; - bool success = (! strcmp (actual, expected)); + bool success = (!strcmp(actual, expected)); - if (success and ! expfail) - { + if (success and !expfail) { ++_passed; - std::cout << green ("ok") - << " " - << _counter - << " - " - << name - << '\n'; - } - else - { - if (success == expfail) - ++_failed; - std::cout << red ("not ok") - << " " - << _counter - << " - " - << name - << (expfail ? (success ? " # FIXED" : " # TODO") : "") - << "\n# expected: '" - << expected - << "'" - << "\n# got: '" - << actual - << "'\n"; + std::cout << green("ok") << " " << _counter << " - " << name << '\n'; + } else { + if (success == expfail) ++_failed; + std::cout << red("not ok") << " " << _counter << " - " << name + << (expfail ? (success ? " # FIXED" : " # TODO") : "") << "\n# expected: '" + << expected << "'" + << "\n# got: '" << actual << "'\n"; } } /////////////////////////////////////////////////////////////////////////////// -void UnitTest::diag (const std::string& text) -{ - auto start = text.find_first_not_of (" \t\n\r\f"); - auto end = text.find_last_not_of (" \t\n\r\f"); - if (start != std::string::npos && - end != std::string::npos) - std::cout << "# " << text.substr (start, end - start + 1) << '\n'; +void UnitTest::diag(const std::string& text) { + auto start = text.find_first_not_of(" \t\n\r\f"); + auto end = text.find_last_not_of(" \t\n\r\f"); + if (start != std::string::npos && end != std::string::npos) + std::cout << "# " << text.substr(start, end - start + 1) << '\n'; } /////////////////////////////////////////////////////////////////////////////// -void UnitTest::pass (const std::string& text) -{ +void UnitTest::pass(const std::string& text) { ++_counter; ++_passed; - std::cout << green ("ok") - << " " - << _counter - << " - " - << text - << '\n'; + std::cout << green("ok") << " " << _counter << " - " << text << '\n'; } /////////////////////////////////////////////////////////////////////////////// -void UnitTest::fail (const std::string& text) -{ +void UnitTest::fail(const std::string& text) { ++_counter; ++_failed; - std::cout << red ("not ok") - << " " - << _counter - << " - " - << text - << '\n'; + std::cout << red("not ok") << " " << _counter << " - " << text << '\n'; } /////////////////////////////////////////////////////////////////////////////// -void UnitTest::skip (const std::string& text) -{ +void UnitTest::skip(const std::string& text) { ++_counter; ++_skipped; - std::cout << yellow ("ok") - << " " - << _counter - << " - " - << text - << " # skip" - << '\n'; + std::cout << yellow("ok") << " " << _counter << " - " << text << " # skip" << '\n'; } /////////////////////////////////////////////////////////////////////////////// -std::string UnitTest::red (const std::string& input) -{ - if (isatty (fileno (stdout))) - return std::string ("\033[31m" + input + "\033[0m"); +std::string UnitTest::red(const std::string& input) { + if (isatty(fileno(stdout))) return std::string("\033[31m" + input + "\033[0m"); return input; } /////////////////////////////////////////////////////////////////////////////// -std::string UnitTest::green (const std::string& input) -{ - if (isatty (fileno (stdout))) - return std::string ("\033[32m" + input + "\033[0m"); +std::string UnitTest::green(const std::string& input) { + if (isatty(fileno(stdout))) return std::string("\033[32m" + input + "\033[0m"); return input; } /////////////////////////////////////////////////////////////////////////////// -std::string UnitTest::yellow (const std::string& input) -{ - if (isatty (fileno (stdout))) - return std::string ("\033[33m" + input + "\033[0m"); +std::string UnitTest::yellow(const std::string& input) { + if (isatty(fileno(stdout))) return std::string("\033[33m" + input + "\033[0m"); return input; } diff --git a/test/test.h b/test/test.h index 21783f188..0c27e8e85 100644 --- a/test/test.h +++ b/test/test.h @@ -29,36 +29,35 @@ #include -class UnitTest -{ -public: - UnitTest (); - UnitTest (int); - ~UnitTest (); +class UnitTest { + public: + UnitTest(); + UnitTest(int); + ~UnitTest(); - void plan (int); - void planMore (int); - void ok (bool, const std::string&, bool expfail = false); - void notok (bool, const std::string&, bool expfail = false); - void is (bool, bool, const std::string&, bool expfail = false); - void is (size_t, size_t, const std::string&, bool expfail = false); - void is (int, int, const std::string&, bool expfail = false); - void is (double, double, const std::string&, bool expfail = false); - void is (double, double, double, const std::string&, bool expfail = false); - void is (unsigned char, unsigned char, const std::string&, bool expfail = false); - void is (const std::string&, const std::string&, const std::string&, bool expfail = false); - void is (const char*, const char*, const std::string&, bool expfail = false); - void diag (const std::string&); - void pass (const std::string&); - void fail (const std::string&); - void skip (const std::string&); + void plan(int); + void planMore(int); + void ok(bool, const std::string&, bool expfail = false); + void notok(bool, const std::string&, bool expfail = false); + void is(bool, bool, const std::string&, bool expfail = false); + void is(size_t, size_t, const std::string&, bool expfail = false); + void is(int, int, const std::string&, bool expfail = false); + void is(double, double, const std::string&, bool expfail = false); + void is(double, double, double, const std::string&, bool expfail = false); + void is(unsigned char, unsigned char, const std::string&, bool expfail = false); + void is(const std::string&, const std::string&, const std::string&, bool expfail = false); + void is(const char*, const char*, const std::string&, bool expfail = false); + void diag(const std::string&); + void pass(const std::string&); + void fail(const std::string&); + void skip(const std::string&); -private: - std::string red (const std::string&); - std::string green (const std::string&); - std::string yellow (const std::string&); + private: + std::string red(const std::string&); + std::string green(const std::string&); + std::string yellow(const std::string&); -private: + private: int _planned; int _counter; int _passed; diff --git a/test/test_hooks/on-exit-misbehave2 b/test/test_hooks/on-exit-misbehave2 index 2b52b012b..338b21284 100644 --- a/test/test_hooks/on-exit-misbehave2 +++ b/test/test_hooks/on-exit-misbehave2 @@ -15,4 +15,3 @@ echo 'FEEDBACK' # - 0: JSON ignored, non-JSON is feedback. # - non-0: JSON ignored, non-JSON is error. exit 0 - diff --git a/test/test_hooks/on-launch-bad b/test/test_hooks/on-launch-bad index 221a51262..01c7cbfdb 100644 --- a/test/test_hooks/on-launch-bad +++ b/test/test_hooks/on-launch-bad @@ -14,4 +14,3 @@ echo 'FEEDBACK' # - 0: JSON ignored, non-JSON is feedback. # - non-0: JSON ignored, non-JSON is error. exit 1 - diff --git a/test/test_hooks/on-launch-good b/test/test_hooks/on-launch-good index e6c6226c2..1c1aefea6 100644 --- a/test/test_hooks/on-launch-good +++ b/test/test_hooks/on-launch-good @@ -14,4 +14,3 @@ echo 'FEEDBACK' # - 0: JSON ignored, non-JSON is feedback. # - non-0: JSON ignored, non-JSON is error. exit 0 - diff --git a/test/test_hooks/on-launch-good-env b/test/test_hooks/on-launch-good-env index 34a55cac5..ffbe3ca62 100644 --- a/test/test_hooks/on-launch-good-env +++ b/test/test_hooks/on-launch-good-env @@ -23,4 +23,3 @@ echo $6 # - 0: JSON ignored, non-JSON is feedback. # - non-0: JSON ignored, non-JSON is error. exit 0 - diff --git a/test/test_hooks/on-launch-misbehave1 b/test/test_hooks/on-launch-misbehave1 index d309739e4..096218612 100644 --- a/test/test_hooks/on-launch-misbehave1 +++ b/test/test_hooks/on-launch-misbehave1 @@ -15,4 +15,3 @@ echo 'FEEDBACK' # - non-0: JSON ignored, non-JSON is error. kill -9 $$ exit 0 - diff --git a/test/test_hooks/on-launch-misbehave2 b/test/test_hooks/on-launch-misbehave2 index f981f8d68..7e46056aa 100644 --- a/test/test_hooks/on-launch-misbehave2 +++ b/test/test_hooks/on-launch-misbehave2 @@ -15,4 +15,3 @@ echo 'FEEDBACK' # - 0: JSON ignored, non-JSON is feedback. # - non-0: JSON ignored, non-JSON is error. exit 0 - diff --git a/test/test_hooks/on-modify-for-template-badexit.py b/test/test_hooks/on-modify-for-template-badexit.py index 32537561e..06f62918c 100644 --- a/test/test_hooks/on-modify-for-template-badexit.py +++ b/test/test_hooks/on-modify-for-template-badexit.py @@ -12,7 +12,7 @@ task["description"] = "This is an example modify hook" # A random message sys.stdout.write("Hello from the template hook\n") -sys.stdout.write(json.dumps(task, separators=(',', ':')) + '\n') +sys.stdout.write(json.dumps(task, separators=(",", ":")) + "\n") sys.exit(1) # vim: ai sts=4 et sw=4 diff --git a/test/test_hooks/on-modify-for-template.py b/test/test_hooks/on-modify-for-template.py index c3b01193e..01cf35a12 100644 --- a/test/test_hooks/on-modify-for-template.py +++ b/test/test_hooks/on-modify-for-template.py @@ -12,7 +12,7 @@ task["description"] = "This is an example modify hook" # A random message sys.stdout.write("Hello from the template hook\n") -sys.stdout.write(json.dumps(task, separators=(',', ':')) + '\n') +sys.stdout.write(json.dumps(task, separators=(",", ":")) + "\n") sys.exit(0) # vim: ai sts=4 et sw=4 diff --git a/test/timesheet.test.py b/test/timesheet.test.py index 83a48a253..2dc9af10d 100755 --- a/test/timesheet.test.py +++ b/test/timesheet.test.py @@ -30,6 +30,7 @@ import re import sys import unittest from time import time + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -53,8 +54,8 @@ class TestTimesheet(TestCase): # C0 completed, this week # C1 completed, last week # C2 completed, 2wks ago - now = int(time()) - seven = now - 7 * 86400 + now = int(time()) + seven = now - 7 * 86400 fourteen = now - 14 * 86400 cls.t("add P0 entry:{0}".format(fourteen)) @@ -76,13 +77,17 @@ class TestTimesheet(TestCase): expected = re.compile( "Started.+PS2.+Completed.+C2.+" "Started.+PS1.+Completed.+C1.+" - "Started.+PS0.+Completed.+C0", re.DOTALL) + "Started.+PS0.+Completed.+C0", + re.DOTALL, + ) self.assertRegex(out, expected) def test_one_week(self): """One week of started and completed""" # This is the default filter, reduced from 4 weeks to 1. - code, out, err = self.t("timesheet (+PENDING and start.after:now-1wk) or (+COMPLETED and end.after:now-1wk)") + code, out, err = self.t( + "timesheet (+PENDING and start.after:now-1wk) or (+COMPLETED and end.after:now-1wk)" + ) expected = re.compile("Started.+PS0.+Completed.+C0", re.DOTALL) self.assertRegex(out, expected) @@ -91,8 +96,10 @@ class TestTimesheet(TestCase): self.assertNotIn("C1", out) self.assertNotIn("C2", out) + if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/tw-1379.test.py b/test/tw-1379.test.py index bc6f2aaaa..f30cdee8b 100755 --- a/test/tw-1379.test.py +++ b/test/tw-1379.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + sys.path.append(os.path.dirname(os.path.abspath(__file__))) from basetest import Task, TestCase @@ -39,7 +40,7 @@ class TestBug1379(TestCase): def setUp(self): self.t = Task() # Themes are a special case that cannot be set via "task config" - with open(self.t.taskrc, 'a') as fh: + with open(self.t.taskrc, "a") as fh: fh.write("include " + REPO_DIR + "/../doc/rc/no-color.theme\n") self.t.config("color.alternate", "") @@ -157,8 +158,10 @@ class TestBug1379(TestCase): code, out, err = self.t("all +DELETED") self.assertRegex(out, self.RED + r".*Delete.*" + self.CLEAR) + if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/tw-1837.test.py b/test/tw-1837.test.py index 7078545a6..78ecbc012 100755 --- a/test/tw-1837.test.py +++ b/test/tw-1837.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + sys.path.append(os.path.dirname(os.path.abspath(__file__))) from basetest import Task, TestCase @@ -50,6 +51,7 @@ from basetest import Task, TestCase # self.assertNotRegex(t, r) # self.tap("") + class TestBug1837(TestCase): def setUp(self): self.t = Task() @@ -61,8 +63,10 @@ class TestBug1837(TestCase): self.tap(out) self.tap(err) + if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/tw-20.test.py b/test/tw-20.test.py index f06fafe8b..a2daa97c1 100755 --- a/test/tw-20.test.py +++ b/test/tw-20.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -48,7 +49,7 @@ class TestBug20(TestCase): self.t.env["VISUAL"] = self.editor def test_annotate_edit_does_not_delete(self): - """ edit annotation should not delete then add untouched annotations """ + """edit annotation should not delete then add untouched annotations""" self.t("add tw-20") self.t("1 annotate 1st annotation") @@ -62,8 +63,8 @@ class TestBug20(TestCase): code, _timestamp1b, err = self.t("_get 1.annotations.1.entry") code, _timestamp2b, err = self.t("_get 1.annotations.2.entry") - self.assertEqual( _timestamp1a, _timestamp1b ) - self.assertEqual( _timestamp2a, _timestamp2b ) + self.assertEqual(_timestamp1a, _timestamp1b) + self.assertEqual(_timestamp2a, _timestamp2b) code, out, err = self.t("info") @@ -73,6 +74,7 @@ class TestBug20(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/tw-2575.test.py b/test/tw-2575.test.py index cd9c75dd1..0638fe49a 100755 --- a/test/tw-2575.test.py +++ b/test/tw-2575.test.py @@ -40,10 +40,41 @@ class TestExport(TestCase): self.assertEqual(len(out), 4) - self.assertTaskEqual(out[0], {"id": 1, "description": "one", "status": "pending", "urgency": 0}) - self.assertTaskEqual(out[1], {"id": 2, "description": "two", "project": "strange", "status": "pending", "urgency": 1}) - self.assertTaskEqual(out[2], {"id": 3, "description": "task1", "status": "pending", "project": "A", "tags": ["home"], "urgency": 16.8}) - self.assertTaskEqual(out[3], {"id": 4, "description": "task2", "status": "pending", "project": "A", "tags": ["work"], "urgency": 1.8}) + self.assertTaskEqual( + out[0], {"id": 1, "description": "one", "status": "pending", "urgency": 0} + ) + self.assertTaskEqual( + out[1], + { + "id": 2, + "description": "two", + "project": "strange", + "status": "pending", + "urgency": 1, + }, + ) + self.assertTaskEqual( + out[2], + { + "id": 3, + "description": "task1", + "status": "pending", + "project": "A", + "tags": ["home"], + "urgency": 16.8, + }, + ) + self.assertTaskEqual( + out[3], + { + "id": 4, + "description": "task2", + "status": "pending", + "project": "A", + "tags": ["work"], + "urgency": 1.8, + }, + ) def test_exports_filter(self): """Verify exports with filter work""" @@ -52,7 +83,9 @@ class TestExport(TestCase): self.assertEqual(len(out), 1) - self.assertTaskEqual(out[0], {"id": 1, "description": "one", "status": "pending", "urgency": 0}) + self.assertTaskEqual( + out[0], {"id": 1, "description": "one", "status": "pending", "urgency": 0} + ) def test_exports_with_limits_and_filter(self): """Verify exports with limits and filter work""" @@ -61,15 +94,45 @@ class TestExport(TestCase): self.assertEqual(len(out), 2) - self.assertTaskEqual(out[0], {"id": 3, "description": "task1", "status": "pending", "project": "A", "tags": ["home"], "urgency": 16.8}) - self.assertTaskEqual(out[1], {"id": 4, "description": "task2", "status": "pending", "project": "A", "tags": ["work"], "urgency": 1.8}) + self.assertTaskEqual( + out[0], + { + "id": 3, + "description": "task1", + "status": "pending", + "project": "A", + "tags": ["home"], + "urgency": 16.8, + }, + ) + self.assertTaskEqual( + out[1], + { + "id": 4, + "description": "task2", + "status": "pending", + "project": "A", + "tags": ["work"], + "urgency": 1.8, + }, + ) code, out, err = self.t("task limit:1 export") out = json.loads(out) self.assertEqual(len(out), 1) - self.assertTaskEqual(out[0], {"id": 3, "description": "task1", "status": "pending", "project": "A", "tags": ["home"], "urgency": 16.8}) + self.assertTaskEqual( + out[0], + { + "id": 3, + "description": "task1", + "status": "pending", + "project": "A", + "tags": ["home"], + "urgency": 16.8, + }, + ) def test_exports_report(self): """Verify exports with report work""" @@ -78,8 +141,28 @@ class TestExport(TestCase): self.assertEqual(len(out), 2) - self.assertTaskEqual(out[0], {"id": 4, "description": "task2", "status": "pending", "project": "A", "tags": ["work"], "urgency": 1.8}) - self.assertTaskEqual(out[1], {"id": 3, "description": "task1", "status": "pending", "project": "A", "tags": ["home"], "urgency": 16.8}) + self.assertTaskEqual( + out[0], + { + "id": 4, + "description": "task2", + "status": "pending", + "project": "A", + "tags": ["work"], + "urgency": 1.8, + }, + ) + self.assertTaskEqual( + out[1], + { + "id": 3, + "description": "task1", + "status": "pending", + "project": "A", + "tags": ["home"], + "urgency": 16.8, + }, + ) if __name__ == "__main__": diff --git a/test/tw-262.test.py b/test/tw-262.test.py index c3a0ff006..74935075e 100755 --- a/test/tw-262.test.py +++ b/test/tw-262.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -77,8 +78,7 @@ class TestBug262(TestCase): self._check_expectation(" (project.isnt:tw)") def test_proj_isnt_parenthesis_space_leading_double(self): - """project.isnt works within parenthesis after a double leading space - """ + """project.isnt works within parenthesis after a double leading space""" self._check_expectation(" ( project.isnt:tw)") def test_proj_isnt_parenthesis_space_trailing(self): @@ -86,8 +86,7 @@ class TestBug262(TestCase): self._check_expectation("(project.isnt:tw) ") def test_proj_isnt_parenthesis_space_trailing_double(self): - """project.isnt works within parenthesis after a double trailing space - """ + """project.isnt works within parenthesis after a double trailing space""" self._check_expectation("(project.isnt:tw ) ") def test_proj_isnt_spaces_parenthesis(self): @@ -98,8 +97,10 @@ class TestBug262(TestCase): """project.isnt works within parenthesis and double spaces""" self._check_expectation(" ( project.isnt:tw ) ") + if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/tw-2689.test.cpp b/test/tw-2689.test.cpp index e18fdb021..14f95a784 100644 --- a/test/tw-2689.test.cpp +++ b/test/tw-2689.test.cpp @@ -24,68 +24,75 @@ // //////////////////////////////////////////////////////////////////////////////// -#include #include + +#include // cmake.h include header must come first -#include #include +#include #include //////////////////////////////////////////////////////////////////////////////// -int main (int, char**) -{ - UnitTest test (12); +int main(int, char**) { + UnitTest test(12); // Ensure environment has no influence. - unsetenv ("TASKDATA"); - unsetenv ("TASKRC"); + unsetenv("TASKDATA"); + unsetenv("TASKRC"); // Inform Task about the attributes in the JSON below Task::attributes["depends"] = "string"; Task::attributes["uuid"] = "string"; // depends in [..] string from a taskserver (issue#2689) - auto sample = "{" - "\"depends\":\"[\\\"92a40a34-37f3-4785-8ca1-ff89cfbfd105\\\",\\\"e08e35fa-e42b-4de0-acc4-518fca8f6365\\\"]\"," - "\"uuid\":\"00000000-0000-0000-0000-000000000000\"" - "}"; - auto json = Task (sample); - auto value = json.get ("uuid"); - test.is (value, "00000000-0000-0000-0000-000000000000", "json [..] uuid"); - value = json.get ("depends"); - test.is (value, "92a40a34-37f3-4785-8ca1-ff89cfbfd105,e08e35fa-e42b-4de0-acc4-518fca8f6365", "json [..] depends"); - test.ok (json.has ("dep_92a40a34-37f3-4785-8ca1-ff89cfbfd105"), "json [..] dep attr"); - test.ok (json.has ("dep_e08e35fa-e42b-4de0-acc4-518fca8f6365"), "json [..] dep attr"); + auto sample = + "{" + "\"depends\":\"[\\\"92a40a34-37f3-4785-8ca1-ff89cfbfd105\\\",\\\"e08e35fa-e42b-4de0-acc4-" + "518fca8f6365\\\"]\"," + "\"uuid\":\"00000000-0000-0000-0000-000000000000\"" + "}"; + auto json = Task(sample); + auto value = json.get("uuid"); + test.is(value, "00000000-0000-0000-0000-000000000000", "json [..] uuid"); + value = json.get("depends"); + test.is(value, "92a40a34-37f3-4785-8ca1-ff89cfbfd105,e08e35fa-e42b-4de0-acc4-518fca8f6365", + "json [..] depends"); + test.ok(json.has("dep_92a40a34-37f3-4785-8ca1-ff89cfbfd105"), "json [..] dep attr"); + test.ok(json.has("dep_e08e35fa-e42b-4de0-acc4-518fca8f6365"), "json [..] dep attr"); // depends in comma-delimited string from a taskserver (deprecated format) - sample = "{" - "\"depends\":\"92a40a34-37f3-4785-8ca1-ff89cfbfd105,e08e35fa-e42b-4de0-acc4-518fca8f6365\"," - "\"uuid\":\"00000000-0000-0000-0000-000000000000\"" - "}"; - json = Task (sample); - value = json.get ("uuid"); - test.is (value, "00000000-0000-0000-0000-000000000000", "json comma-separated uuid"); - value = json.get ("depends"); - test.is (value, "92a40a34-37f3-4785-8ca1-ff89cfbfd105,e08e35fa-e42b-4de0-acc4-518fca8f6365", "json comma-separated depends"); - test.ok (json.has ("dep_92a40a34-37f3-4785-8ca1-ff89cfbfd105"), "json comma-separated dep attr"); - test.ok (json.has ("dep_e08e35fa-e42b-4de0-acc4-518fca8f6365"), "json comma-separated dep attr"); + sample = + "{" + "\"depends\":\"92a40a34-37f3-4785-8ca1-ff89cfbfd105,e08e35fa-e42b-4de0-acc4-518fca8f6365\"," + "\"uuid\":\"00000000-0000-0000-0000-000000000000\"" + "}"; + json = Task(sample); + value = json.get("uuid"); + test.is(value, "00000000-0000-0000-0000-000000000000", "json comma-separated uuid"); + value = json.get("depends"); + test.is(value, "92a40a34-37f3-4785-8ca1-ff89cfbfd105,e08e35fa-e42b-4de0-acc4-518fca8f6365", + "json comma-separated depends"); + test.ok(json.has("dep_92a40a34-37f3-4785-8ca1-ff89cfbfd105"), "json comma-separated dep attr"); + test.ok(json.has("dep_e08e35fa-e42b-4de0-acc4-518fca8f6365"), "json comma-separated dep attr"); // depends in a JSON array from a taskserver - sample = "{" - "\"depends\":[\"92a40a34-37f3-4785-8ca1-ff89cfbfd105\",\"e08e35fa-e42b-4de0-acc4-518fca8f6365\"]," - "\"uuid\":\"00000000-0000-0000-0000-000000000000\"" - "}"; - json = Task (sample); - value = json.get ("uuid"); - test.is (value, "00000000-0000-0000-0000-000000000000", "json array uuid"); - value = json.get ("depends"); - test.is (value, "92a40a34-37f3-4785-8ca1-ff89cfbfd105,e08e35fa-e42b-4de0-acc4-518fca8f6365", "json array depends"); - test.ok (json.has ("dep_92a40a34-37f3-4785-8ca1-ff89cfbfd105"), "json array dep attr"); - test.ok (json.has ("dep_e08e35fa-e42b-4de0-acc4-518fca8f6365"), "json array dep attr"); + sample = + "{" + "\"depends\":[\"92a40a34-37f3-4785-8ca1-ff89cfbfd105\",\"e08e35fa-e42b-4de0-acc4-" + "518fca8f6365\"]," + "\"uuid\":\"00000000-0000-0000-0000-000000000000\"" + "}"; + json = Task(sample); + value = json.get("uuid"); + test.is(value, "00000000-0000-0000-0000-000000000000", "json array uuid"); + value = json.get("depends"); + test.is(value, "92a40a34-37f3-4785-8ca1-ff89cfbfd105,e08e35fa-e42b-4de0-acc4-518fca8f6365", + "json array depends"); + test.ok(json.has("dep_92a40a34-37f3-4785-8ca1-ff89cfbfd105"), "json array dep attr"); + test.ok(json.has("dep_e08e35fa-e42b-4de0-acc4-518fca8f6365"), "json array dep attr"); return 0; } //////////////////////////////////////////////////////////////////////////////// - diff --git a/test/tw-295.test.py b/test/tw-295.test.py index b46a892c2..0cb9932e1 100755 --- a/test/tw-295.test.py +++ b/test/tw-295.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + sys.path.append(os.path.dirname(os.path.abspath(__file__))) from basetest import Task, TestCase @@ -39,7 +40,7 @@ class TestBug295(TestCase): def test_subst_with_slashes(self): """Test substitution containing slashes""" - self.t('add -- one/two/three') + self.t("add -- one/two/three") # Python string contains \\\\, converts to internal \\. # Something in the command processing converts \\ --> \. @@ -49,12 +50,14 @@ class TestBug295(TestCase): # code, out, err = self.t('rc.debug.parser=2 1 modify /\\\\/two\\\\//TWO/') # self.tap(err) - self.t('1 modify /\\\\/two\\\\//TWO/') - code, out, err = self.t('list') - self.assertIn('oneTWOthree', out) + self.t("1 modify /\\\\/two\\\\//TWO/") + code, out, err = self.t("list") + self.assertIn("oneTWOthree", out) + if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/tw-3527.test.py b/test/tw-3527.test.py index a6674f60c..94b81e7ff 100755 --- a/test/tw-3527.test.py +++ b/test/tw-3527.test.py @@ -35,5 +35,5 @@ class TestExport(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner - unittest.main(testRunner=TAPTestRunner()) + unittest.main(testRunner=TAPTestRunner()) diff --git a/test/uda.test.py b/test/uda.test.py index 1c9901e4f..1919e8600 100755 --- a/test/uda.test.py +++ b/test/uda.test.py @@ -29,6 +29,7 @@ import sys import os import re import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -179,8 +180,7 @@ class TestUdaDuration(TestBaseUda): """Add tasks with an invalid UDA duration""" code, out, err = self.t.runError("add bad extra:bad_duration") self.assertNotIn("Created task", out) - self.assertIn("The duration value 'bad_duration' is not supported", - err) + self.assertIn("The duration value 'bad_duration' is not supported", err) class TestUdaNumeric(TestBaseUda): @@ -254,8 +254,7 @@ class TestUdaValue(TestBaseUda): self.assertIn("Created task", out) code, out, err = self.t.runError("add two extra:toxic") - self.assertIn("The 'extra' attribute does not allow a value of " - "'toxic'", err) + self.assertIn("The 'extra' attribute does not allow a value of " "'toxic'", err) code, out, err = self.t("uda") self.assertRegex(out, r"1\s+strong\s+one") @@ -299,8 +298,8 @@ class TestBug21(TestCase): def test_almost_UDA(self): """21: do not match a UDA if not followed by colon""" - self.t.config('uda.foo.type', 'string') - self.t.config('uda.foo.label', 'FOO') + self.t.config("uda.foo.type", "string") + self.t.config("uda.foo.label", "FOO") self.t("add this is a foo bar") code, out, err = self.t("1 info") @@ -314,12 +313,12 @@ class Test1447(TestCase): def test_filter_uda(self): """1447: Verify ability to filter on empty UDA that resembles named date""" - self.t.config('uda.sep.type', 'string') - self.t('add one') - self.t('add two sep:foo') - code, out, err = self.t('sep: list') + self.t.config("uda.sep.type", "string") + self.t("add one") + self.t("add two sep:foo") + code, out, err = self.t("sep: list") self.assertEqual(0, code, "Exit code was non-zero ({0})".format(code)) - self.assertIn('one', out) + self.assertIn("one", out) class Test1542(TestCase): @@ -333,18 +332,18 @@ class Test1542(TestCase): 1542: Make sure the numeric UDA value 1187962 does not get converted to scientific notation on export. """ - self.t('add large bugid:1187962') - code, out, err = self.t('1 export') - self.assertIn("\"bugid\":1187962,", out) + self.t("add large bugid:1187962") + code, out, err = self.t("1 export") + self.assertIn('"bugid":1187962,', out) def test_small_numeric_uda_retains_value(self): """ 1542: Make sure the numeric UDA value 43.21 does not get converted to integer on export. """ - self.t('add small bugid:43.21') - code, out, err = self.t('1 export') - self.assertIn("\"bugid\":43.21", out) + self.t("add small bugid:43.21") + code, out, err = self.t("1 export") + self.assertIn('"bugid":43.21', out) class TestBug1622(TestCase): @@ -363,6 +362,7 @@ class TestBug1622(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/uda_orphan.test.py b/test/uda_orphan.test.py index edceaafab..0ba3e9c03 100755 --- a/test/uda_orphan.test.py +++ b/test/uda_orphan.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -47,7 +48,9 @@ class TestUDAOrphans(TestCase): """Verify that orphans are preserved during various operations""" self.t("rc.uda.extra.type:string rc.uda.extra.label:Extra add one extra:foo") - code, out, err = self.t("rc.uda.extra.type:string rc.uda.extra.label:Extra _get 1.extra") + code, out, err = self.t( + "rc.uda.extra.type:string rc.uda.extra.label:Extra _get 1.extra" + ) self.assertEqual("foo\n", out) # DOM access for orphans is not supported. @@ -97,11 +100,12 @@ class TestUDAOrphans(TestCase): # Only the first task should be identified as orphan code, out, err = self.t("udas") - self.assertRegex(out, r'extra\s+1\s+1 Orphan UDA') + self.assertRegex(out, r"extra\s+1\s+1 Orphan UDA") if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/uda_report.test.py b/test/uda_report.test.py index 427b20660..b4853c478 100755 --- a/test/uda_report.test.py +++ b/test/uda_report.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -69,6 +70,7 @@ class TestUdaReports(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/uda_sort.test.py b/test/uda_sort.test.py index a8274672e..29116d5e4 100755 --- a/test/uda_sort.test.py +++ b/test/uda_sort.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -38,89 +39,89 @@ class TestUDACustomSort(TestCase): @classmethod def setUpClass(cls): cls.t = Task() - cls.t.config('uda.foo.type', 'string') - cls.t.config('uda.foo.label', 'Foo') - cls.t.config('uda.foo.values', 'H,M,L,') - cls.t.config('report.list.columns', 'id,description,foo') - cls.t.config('report.list.labels', 'ID,Desc,Foo') - cls.t('add four foo:H') - cls.t('add three foo:M') - cls.t('add two foo:L') - cls.t('add one') + cls.t.config("uda.foo.type", "string") + cls.t.config("uda.foo.label", "Foo") + cls.t.config("uda.foo.values", "H,M,L,") + cls.t.config("report.list.columns", "id,description,foo") + cls.t.config("report.list.labels", "ID,Desc,Foo") + cls.t("add four foo:H") + cls.t("add three foo:M") + cls.t("add two foo:L") + cls.t("add one") def test_ascending(self): """Ascending custom sort order""" - self.t.config('uda.foo.values', 'H,M,L,') - code, out, err = self.t('rc.report.list.sort:foo+ list') + self.t.config("uda.foo.values", "H,M,L,") + code, out, err = self.t("rc.report.list.sort:foo+ list") - one = out.find('one') - two = out.find('two') - three = out.find('three') - four = out.find('four') + one = out.find("one") + two = out.find("two") + three = out.find("three") + four = out.find("four") - self.assertTrue(one < two) - self.assertTrue(two < three) + self.assertTrue(one < two) + self.assertTrue(two < three) self.assertTrue(three < four) def test_descending(self): """Descending custom sort order""" - self.t.config('uda.foo.values', 'H,M,L,') - code, out, err = self.t('rc.report.list.sort:foo- list') + self.t.config("uda.foo.values", "H,M,L,") + code, out, err = self.t("rc.report.list.sort:foo- list") - one = out.find('one') - two = out.find('two') - three = out.find('three') - four = out.find('four') + one = out.find("one") + two = out.find("two") + three = out.find("three") + four = out.find("four") - self.assertTrue(four < three) + self.assertTrue(four < three) self.assertTrue(three < two) - self.assertTrue(two < one) + self.assertTrue(two < one) def test_ridiculous(self): """Ridiculous custom sort order""" - self.t.config('uda.foo.values', 'H,M,,L') - code, out, err = self.t('rc.report.list.sort:foo- list') + self.t.config("uda.foo.values", "H,M,,L") + code, out, err = self.t("rc.report.list.sort:foo- list") - one = out.find('one') - two = out.find('two') - three = out.find('three') - four = out.find('four') + one = out.find("one") + two = out.find("two") + three = out.find("three") + four = out.find("four") - self.assertTrue(four < three) + self.assertTrue(four < three) self.assertTrue(three < one) - self.assertTrue(one < two) + self.assertTrue(one < two) class TestUDADefaultSort(TestCase): @classmethod def setUpClass(cls): cls.t = Task() - cls.t.config('uda.foo.type', 'string') - cls.t.config('uda.foo.label', 'Foo') - cls.t.config('report.list.columns', 'id,description,foo') - cls.t.config('report.list.labels', 'ID,Desc,Foo') - cls.t('add one foo:A') - cls.t('add three') - cls.t('add two foo:B') + cls.t.config("uda.foo.type", "string") + cls.t.config("uda.foo.label", "Foo") + cls.t.config("report.list.columns", "id,description,foo") + cls.t.config("report.list.labels", "ID,Desc,Foo") + cls.t("add one foo:A") + cls.t("add three") + cls.t("add two foo:B") def test_ascending(self): """Ascending default sort order""" - code, out, err = self.t('rc.report.list.sort:foo+ list') + code, out, err = self.t("rc.report.list.sort:foo+ list") - one = out.find('one') - two = out.find('two') - three = out.find('three') + one = out.find("one") + two = out.find("two") + three = out.find("three") self.assertTrue(one < two) self.assertTrue(two < three) def test_descending(self): """Descending default sort order""" - code, out, err = self.t('rc.report.list.sort:foo- list') + code, out, err = self.t("rc.report.list.sort:foo- list") - one = out.find('one') - two = out.find('two') - three = out.find('three') + one = out.find("one") + two = out.find("two") + three = out.find("three") self.assertTrue(one < three) self.assertTrue(two < one) @@ -133,12 +134,12 @@ class TestBug1319(TestCase): def test_uda_sorting(self): """1319: Verify that UDAs are sorted according to defined order""" - self.t.config("uda.when.type", "string") - self.t.config("uda.when.values", "night,evening,noon,morning") + self.t.config("uda.when.type", "string") + self.t.config("uda.when.values", "night,evening,noon,morning") self.t.config("report.foo.columns", "id,when,description") - self.t.config("report.foo.labels", "ID,WHEN,DESCRIPTION") - self.t.config("report.foo.sort", "when+") + self.t.config("report.foo.labels", "ID,WHEN,DESCRIPTION") + self.t.config("report.foo.sort", "when+") self.t("add one when:night") self.t("add two when:evening") @@ -146,11 +147,15 @@ class TestBug1319(TestCase): self.t("add four when:morning") code, out, err = self.t("rc.verbose:nothing foo") - self.assertRegex(out, r"4\s+morning\s+four\s+3\s+noon\s+three\s+2\s+evening\s+two\s+1\s+night\s+one") + self.assertRegex( + out, + r"4\s+morning\s+four\s+3\s+noon\s+three\s+2\s+evening\s+two\s+1\s+night\s+one", + ) if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/undo.test.py b/test/undo.test.py index b50acb0cc..b0beca1b1 100755 --- a/test/undo.test.py +++ b/test/undo.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -41,24 +42,24 @@ class TestUndo(TestCase): def test_add_undo(self): """'add' then 'undo'""" - self.t('add one') - code, out, err = self.t('_get 1.status') - self.assertEqual(out.strip(), 'pending') - self.t('undo', input="y\n") - code, out, err = self.t('_get 1.status') - self.assertEqual(out.strip(), '') + self.t("add one") + code, out, err = self.t("_get 1.status") + self.assertEqual(out.strip(), "pending") + self.t("undo", input="y\n") + code, out, err = self.t("_get 1.status") + self.assertEqual(out.strip(), "") def test_add_done_undo(self): """'add' then 'done' then 'undo'""" - self.t('add two') - code, out, err = self.t('_get 1.status') - self.assertEqual(out.strip(), 'pending') - self.t('1 done') - code, out, err = self.t('_get 1.status') - self.assertEqual(out.strip(), 'completed') - self.t('undo', input="y\n") - code, out, err = self.t('_get 1.status') - self.assertEqual(out.strip(), 'pending') + self.t("add two") + code, out, err = self.t("_get 1.status") + self.assertEqual(out.strip(), "pending") + self.t("1 done") + code, out, err = self.t("_get 1.status") + self.assertEqual(out.strip(), "completed") + self.t("undo", input="y\n") + code, out, err = self.t("_get 1.status") + self.assertEqual(out.strip(), "pending") def test_undo_en_passant(self): """Verify that en-passant changes during undo are an error""" @@ -73,7 +74,7 @@ class TestUndoStyle(TestCase): self.t("add one project:foo priority:H") self.t("1 modify +tag project:bar priority:") - @unittest.expectedFailure # undo diffs are not supported + @unittest.expectedFailure # undo diffs are not supported def test_undo_side_style(self): """Test that 'rc.undo.style:side' generates the right output""" self.t.config("undo.style", "side") @@ -81,7 +82,7 @@ class TestUndoStyle(TestCase): self.assertNotRegex(out, "-tags:\\s*\n\\+tags:\\s+tag") self.assertRegex(out, r"tags\s+tag\s*") - @unittest.expectedFailure # undo diffs are not supported + @unittest.expectedFailure # undo diffs are not supported def test_undo_diff_style(self): """Test that 'rc.undo.style:diff' generates the right output""" self.t.config("undo.style", "diff") @@ -114,11 +115,12 @@ class TestBug634(TestCase): # If a prompt happens, the test will timeout on input (exitcode != 0) code, out, err = self.t("rc.confirmation=off undo") code, out, err = self.t("_get 1.description") - self.assertEqual(out.strip(), '') # task is gone + self.assertEqual(out.strip(), "") # task is gone if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/unicode.test.py b/test/unicode.test.py index d18cc0239..8c7491870 100755 --- a/test/unicode.test.py +++ b/test/unicode.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -46,13 +47,19 @@ class TestUnicode(TestCase): self.t("add ¥£€¢₡₢₣₤₥₦₧₨₩₪₫₭₮₯ ") self.t("add Pchnąć w tę łódź jeża lub ośm skrzyń fig") self.t("add ๏ เป็นมนุษย์สุดประเสริฐเลิศคุณค่า") - self.t("add イロハニホヘト チリヌルヲ ワカヨタレソ ツネナラムイ ロハニホヘト チリヌルヲ ワカヨタレソ ツネナラム") + self.t( + "add イロハニホヘト チリヌルヲ ワカヨタレソ ツネナラムイ ロハニホヘト チリヌルヲ ワカヨタレソ ツネナラム" + ) self.t("add いろはにほへとちりぬるを") - self.t("add D\\'fhuascail Íosa, Úrmhac na hÓighe Beannaithe, pór Éava agus Ádhaimh") + self.t( + "add D\\'fhuascail Íosa, Úrmhac na hÓighe Beannaithe, pór Éava agus Ádhaimh" + ) self.t("add Árvíztűrő tükörfúrógép") self.t("add Kæmi ný öxi hér ykist þjófum nú bæði víl og ádrepa") self.t("add Sævör grét áðan því úlpan var ónýt") - self.t("add Quizdeltagerne spiste jordbær med fløde, mens cirkusklovnen Wolther spillede på xylofon.") + self.t( + "add Quizdeltagerne spiste jordbær med fløde, mens cirkusklovnen Wolther spillede på xylofon." + ) self.t("add Falsches Üben von Xylophonmusik quält jeden größeren Zwerg") self.t("add Zwölf Boxkämpfer jagten Eva quer über den Sylter Deich") self.t("add Heizölrückstoßabdämpfung") @@ -71,15 +78,15 @@ class TestUnicode(TestCase): def test_utf8_tag(self): """Verify that UTF8 can be used in a tag""" - self.t("add utf8 in tag +Zwölf"); + self.t("add utf8 in tag +Zwölf") code, out, err = self.t("_get 1.tags") - self.assertEqual("Zwölf\n", out); + self.assertEqual("Zwölf\n", out) def test_unicode_escape1(self): """Verify U+NNNN unicode sequences""" self.t("add Price U+20AC4") code, out, err = self.t("_get 1.description") - self.assertEqual("Price €4\n", out); + self.assertEqual("Price €4\n", out) def test_unicode_escape2(self): """Verify \\uNNNN unicode sequences""" @@ -92,10 +99,12 @@ class TestUnicode(TestCase): # $ echo add 'Price \u20A43' # \ is preserved self.t(r"add 'Price \u20A43'") code, out, err = self.t("_get 1.description") - self.assertEqual("Price ₤3\n", out); + self.assertEqual("Price ₤3\n", out) + if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/unique.test.py b/test/unique.test.py index efa9d12eb..2204b0e9a 100755 --- a/test/unique.test.py +++ b/test/unique.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -67,18 +68,18 @@ class TestUnique(TestCase): def test_unique_status(self): """Verify that unique status values are correctly counted""" code, out, err = self.t("_unique status") - self.assertIn("pending", out) + self.assertIn("pending", out) self.assertIn("completed", out) - self.assertIn("deleted", out) + self.assertIn("deleted", out) def test_unique_description(self): """Verify that unique description values are correctly counted""" code, out, err = self.t("_unique description") - self.assertIn("one", out) - self.assertIn("two", out) + self.assertIn("one", out) + self.assertIn("two", out) self.assertIn("three", out) - self.assertIn("four", out) - self.assertIn("five", out) + self.assertIn("four", out) + self.assertIn("five", out) def test_unique_id(self): """Verify that unique id values are correctly counted""" @@ -92,6 +93,7 @@ class TestUnique(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/upgrade.test.py b/test/upgrade.test.py index 021591a36..d022cc7ee 100755 --- a/test/upgrade.test.py +++ b/test/upgrade.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -60,6 +61,7 @@ class TestUpgrade(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/urgency.test.py b/test/urgency.test.py index 6ab72f087..489dd786b 100755 --- a/test/urgency.test.py +++ b/test/urgency.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -39,94 +40,94 @@ class TestUrgency(TestCase): def setUpClass(cls): """Executed once before any test in the class""" cls.t = Task() - cls.t.config("urgency.uda.priority.H.coefficient", "10") - cls.t.config("urgency.uda.priority.M.coefficient", "6.5") - cls.t.config("urgency.uda.priority.L.coefficient", "3") - cls.t.config("urgency.active.coefficient", "10") - cls.t.config("urgency.project.coefficient", "10") - cls.t.config("urgency.due.coefficient", "10") - cls.t.config("urgency.blocking.coefficient", "10") - cls.t.config("urgency.blocked.coefficient", "10") - cls.t.config("urgency.annotations.coefficient", "10") - cls.t.config("urgency.tags.coefficient", "10") - cls.t.config("urgency.waiting.coefficient", "-10") - cls.t.config("urgency.user.tag.next.coefficient", "10") + cls.t.config("urgency.uda.priority.H.coefficient", "10") + cls.t.config("urgency.uda.priority.M.coefficient", "6.5") + cls.t.config("urgency.uda.priority.L.coefficient", "3") + cls.t.config("urgency.active.coefficient", "10") + cls.t.config("urgency.project.coefficient", "10") + cls.t.config("urgency.due.coefficient", "10") + cls.t.config("urgency.blocking.coefficient", "10") + cls.t.config("urgency.blocked.coefficient", "10") + cls.t.config("urgency.annotations.coefficient", "10") + cls.t.config("urgency.tags.coefficient", "10") + cls.t.config("urgency.waiting.coefficient", "-10") + cls.t.config("urgency.user.tag.next.coefficient", "10") cls.t.config("urgency.user.project.PROJECT.coefficient", "10") - cls.t.config("urgency.user.tag.TAG.coefficient", "10") - cls.t.config("confirmation", "0") + cls.t.config("urgency.user.tag.TAG.coefficient", "10") + cls.t.config("confirmation", "0") - cls.t("add control") # 1 + cls.t("add control") # 1 - cls.t("add 1a pri:H") # 2 - cls.t("add 1b pri:M") # 3 - cls.t("add 1c pri:L") # 4 + cls.t("add 1a pri:H") # 2 + cls.t("add 1b pri:M") # 3 + cls.t("add 1c pri:L") # 4 - cls.t("add 2a project:P") # 5 + cls.t("add 2a project:P") # 5 - cls.t("add 3a") # 6 + cls.t("add 3a") # 6 cls.t("6 start") - cls.t("add 4a +next") # 7 + cls.t("add 4a +next") # 7 - cls.t("add 5a +one") # 8 - cls.t("add 5b +one +two") # 9 - cls.t("add 5c +one +two +three") # 10 - cls.t("add 5d +one +two +three +four") # 11 + cls.t("add 5a +one") # 8 + cls.t("add 5b +one +two") # 9 + cls.t("add 5c +one +two +three") # 10 + cls.t("add 5d +one +two +three +four") # 11 - cls.t("add 6a") # 12 + cls.t("add 6a") # 12 cls.t("12 annotate A") - cls.t("add 6b") # 13 + cls.t("add 6b") # 13 cls.t("13 annotate A") cls.t("13 annotate B") - cls.t("add 6c") # 14 + cls.t("add 6c") # 14 cls.t("14 annotate A") cls.t("14 annotate B") cls.t("14 annotate C") - cls.t("add 6d") # 15 + cls.t("add 6d") # 15 cls.t("15 annotate A") cls.t("15 annotate B") cls.t("15 annotate C") cls.t("15 annotate D") - cls.t("add 7a wait:10y") # 16 + cls.t("add 7a wait:10y") # 16 - cls.t("add 8a") # 17 - cls.t("add 8b depends:17") # 18 + cls.t("add 8a") # 17 + cls.t("add 8b depends:17") # 18 - cls.t("add 9a due:-10d") # 19 - cls.t("add 9b due:-7d") # 20 - cls.t("add 9c due:-6d") # 21 - cls.t("add 9d due:-5d") # 22 - cls.t("add 9e due:-4d") # 23 - cls.t("add 9f due:-3d") # 24 - cls.t("add 9g due:-2d") # 25 - cls.t("add 9h due:-1d") # 26 - cls.t("add 9i due:now") # 27 - cls.t("add 9j due:25h") # 28 - cls.t("add 9k due:49h") # 29 - cls.t("add 9l due:73h") # 30 - cls.t("add 9m due:97h") # 31 - cls.t("add 9n due:121h") # 32 - cls.t("add 9o due:145h") # 33 - cls.t("add 9p due:169h") # 34 - cls.t("add 9q due:193h") # 35 - cls.t("add 9r due:217h") # 36 - cls.t("add 9s due:241h") # 37 - cls.t("add 9t due:265h") # 38 - cls.t("add 9u due:289h") # 39 - cls.t("add 9v due:313h") # 40 - cls.t("add 9w due:337h") # 41 - cls.t("add 9x due:361h") # 42 + cls.t("add 9a due:-10d") # 19 + cls.t("add 9b due:-7d") # 20 + cls.t("add 9c due:-6d") # 21 + cls.t("add 9d due:-5d") # 22 + cls.t("add 9e due:-4d") # 23 + cls.t("add 9f due:-3d") # 24 + cls.t("add 9g due:-2d") # 25 + cls.t("add 9h due:-1d") # 26 + cls.t("add 9i due:now") # 27 + cls.t("add 9j due:25h") # 28 + cls.t("add 9k due:49h") # 29 + cls.t("add 9l due:73h") # 30 + cls.t("add 9m due:97h") # 31 + cls.t("add 9n due:121h") # 32 + cls.t("add 9o due:145h") # 33 + cls.t("add 9p due:169h") # 34 + cls.t("add 9q due:193h") # 35 + cls.t("add 9r due:217h") # 36 + cls.t("add 9s due:241h") # 37 + cls.t("add 9t due:265h") # 38 + cls.t("add 9u due:289h") # 39 + cls.t("add 9v due:313h") # 40 + cls.t("add 9w due:337h") # 41 + cls.t("add 9x due:361h") # 42 - cls.t("add 10a project:PROJECT") # 43 + cls.t("add 10a project:PROJECT") # 43 - cls.t("add 11a +TAG") # 44 + cls.t("add 11a +TAG") # 44 - cls.t("add 12a scheduled:30d") # 45 - cls.t("add 12b scheduled:yesterday") # 46 + cls.t("add 12a scheduled:30d") # 45 + cls.t("add 12b scheduled:yesterday") # 46 - cls.t("add 13 pri:H") # 47 + cls.t("add 13 pri:H") # 47 def assertApproximately(self, target, value): """Verify that the number in 'value' is within the range""" @@ -263,7 +264,9 @@ class TestUrgency(TestCase): def test_urgency_coefficient_override(self): """Verify urgency coefficient override""" - code, out, err = self.t("rc.urgency.uda.priority.H.coefficient:0.01234 _get 47.urgency") + code, out, err = self.t( + "rc.urgency.uda.priority.H.coefficient:0.01234 _get 47.urgency" + ) self.assertApproximately(0.01234, out) def test_urgency_no_task(self): @@ -297,13 +300,13 @@ class TestBug837(TestCase): def test_unblocked_urgency(self): """837: Verify urgency goes to zero after unblocking - Bug 837: When a task is completed, tasks that depended upon it do not - have the correct urgency and depend on 0 when edited + Bug 837: When a task is completed, tasks that depended upon it do not + have the correct urgency and depend on 0 when edited """ self.t("add one") self.t("add two dep:1") - self.t("list") # GC/handleRecurrence + self.t("list") # GC/handleRecurrence code, out, err = self.t("_get 1.urgency") self.assertEqual("8\n", out) @@ -312,7 +315,7 @@ class TestBug837(TestCase): self.assertEqual("-5\n", out) self.t("1 done") - self.t("list") # GC/handleRecurrence + self.t("list") # GC/handleRecurrence code, out, err = self.t("_get 1.urgency") self.assertEqual("0\n", out) @@ -320,6 +323,7 @@ class TestBug837(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/urgency_inherit.test.py b/test/urgency_inherit.test.py index ac38aa6a9..3df1c42fb 100755 --- a/test/urgency_inherit.test.py +++ b/test/urgency_inherit.test.py @@ -29,6 +29,7 @@ import sys import os import unittest import json + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -78,6 +79,7 @@ class TestUrgencyInherit(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/util.test.cpp b/test/util.test.cpp index 36276a38b..a627c16a9 100644 --- a/test/util.test.cpp +++ b/test/util.test.cpp @@ -27,22 +27,22 @@ #include // cmake.h include header must come first -#include -#include #include -#include +#include #include +#include + +#include //////////////////////////////////////////////////////////////////////////////// -int main (int, char**) -{ - UnitTest t (19); +int main(int, char**) { + UnitTest t(19); Context context; Context::setContext(&context); // Ensure environment has no influence. - unsetenv ("TASKDATA"); - unsetenv ("TASKRC"); + unsetenv("TASKDATA"); + unsetenv("TASKRC"); // TODO int confirm4 (const std::string&); @@ -50,46 +50,48 @@ int main (int, char**) // TODO These are in feedback.cpp, not util.cpp. Task left; - left.set ("zero", "0"); - left.set ("one", 1); - left.set ("two", 2); + left.set("zero", "0"); + left.set("one", 1); + left.set("two", 2); Task right; - right.set ("zero", "00"); - right.set ("two", 2); - right.set ("three", 3); + right.set("zero", "00"); + right.set("two", 2); + right.set("three", 3); - Task rightAgain (right); + Task rightAgain(right); - std::string output = left.diff (right); - t.ok (!(left == right), "Detected changes"); - t.ok (output.find ("Zero will be changed from '0' to '00'") != std::string::npos, "Detected change zero:0 -> zero:00"); - t.ok (output.find ("One will be deleted") != std::string::npos, "Detected deletion one:1 ->"); - t.ok (output.find ("Two") == std::string::npos, "Detected no change two:2 -> two:2"); - t.ok (output.find ("Three will be set to '3'") != std::string::npos, "Detected addition -> three:3"); + std::string output = left.diff(right); + t.ok(!(left == right), "Detected changes"); + t.ok(output.find("Zero will be changed from '0' to '00'") != std::string::npos, + "Detected change zero:0 -> zero:00"); + t.ok(output.find("One will be deleted") != std::string::npos, "Detected deletion one:1 ->"); + t.ok(output.find("Two") == std::string::npos, "Detected no change two:2 -> two:2"); + t.ok(output.find("Three will be set to '3'") != std::string::npos, + "Detected addition -> three:3"); - output = right.diff (rightAgain); - t.ok (output.find ("No changes will be made") != std::string::npos, "No changes detected"); + output = right.diff(rightAgain); + t.ok(output.find("No changes will be made") != std::string::npos, "No changes detected"); - // std::vector indentProject (const std::string&, const std::string whitespace=" ", char delimiter='.'); - t.is (indentProject (""), "", "indentProject '' -> ''"); - t.is (indentProject ("one"), "one", "indentProject 'one' -> 'one'"); - t.is (indentProject ("one.two"), " two", "indentProject 'one.two' -> ' two'"); - t.is (indentProject ("one.two.three"), " three", "indentProject 'one.two.three' -> ' three'"); + // std::vector indentProject (const std::string&, const std::string whitespace=" ", + // char delimiter='.'); + t.is(indentProject(""), "", "indentProject '' -> ''"); + t.is(indentProject("one"), "one", "indentProject 'one' -> 'one'"); + t.is(indentProject("one.two"), " two", "indentProject 'one.two' -> ' two'"); + t.is(indentProject("one.two.three"), " three", "indentProject 'one.two.three' -> ' three'"); // bool nontrivial (const std::string&); - t.notok (nontrivial (""), "nontrivial '' -> false"); - t.notok (nontrivial (" "), "nontrivial ' ' -> false"); - t.notok (nontrivial ("\t\t"), "nontrivial '\\t\\t' -> false"); - t.notok (nontrivial (" \t \t"), "nontrivial ' \\t \\t' -> false"); - t.ok (nontrivial ("a"), "nontrivial 'a' -> true"); - t.ok (nontrivial (" a"), "nontrivial ' a' -> true"); - t.ok (nontrivial ("a "), "nontrivial 'a ' -> true"); - t.ok (nontrivial (" \t\ta"), "nontrivial ' \\t\\ta' -> true"); - t.ok (nontrivial ("a\t\t "), "nontrivial 'a\\t\\t ' -> true"); + t.notok(nontrivial(""), "nontrivial '' -> false"); + t.notok(nontrivial(" "), "nontrivial ' ' -> false"); + t.notok(nontrivial("\t\t"), "nontrivial '\\t\\t' -> false"); + t.notok(nontrivial(" \t \t"), "nontrivial ' \\t \\t' -> false"); + t.ok(nontrivial("a"), "nontrivial 'a' -> true"); + t.ok(nontrivial(" a"), "nontrivial ' a' -> true"); + t.ok(nontrivial("a "), "nontrivial 'a ' -> true"); + t.ok(nontrivial(" \t\ta"), "nontrivial ' \\t\\ta' -> true"); + t.ok(nontrivial("a\t\t "), "nontrivial 'a\\t\\t ' -> true"); return 0; } //////////////////////////////////////////////////////////////////////////////// - diff --git a/test/uuid.test.py b/test/uuid.test.py index ca42036b7..5227cb616 100755 --- a/test/uuid.test.py +++ b/test/uuid.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -40,7 +41,9 @@ class TestUUID(TestCase): self.t.config("dateformat", "m/d/Y") - self.t("import -", input="""[ + self.t( + "import -", + input="""[ {"description":"one", "entry":"1315260230", "status":"pending", "uuid":"9deed7ca-843d-4259-b2c4-40ce73e8e4f3"}, {"description":"two", "entry":"1315260230", "status":"pending", "uuid":"0f4c83d2-552f-4108-ae3f-ccc7959f84a3"}, {"description":"three", "entry":"1315260230", "status":"pending", "uuid":"aa4abef1-1dc5-4a43-b6a0-7872df3094bb"}, @@ -51,7 +54,8 @@ class TestUUID(TestCase): {"description":"seven", "end":"1315338826", "entry":"1315338726", "status":"completed", "uuid":"abcdefab-abcd-abcd-abcd-abcdefabcdef"}, {"description":"eenndd", "end":"1315335841", "entry":"1315335841", "start":"1315338516", "status":"completed", "uuid":"727baa6c-65b8-485e-a810-e133e3cd83dc"}, {"description":"UUNNDDOO", "end":"1315338626", "entry":"1315338626", "status":"completed", "uuid":"c1361003-948e-43e8-85c8-15d28dc3c71c"} - ]""") + ]""", + ) def _config_unittest_report(self): self.t.config("report.unittest.columns", "id,entry,start,description") @@ -210,18 +214,19 @@ class TestFeature891(TestCase): def test_uuid_filter(self): """891: Test that a task is addressable using UUIDs of length 7 - 36""" - for i in range(35,7,-1): + for i in range(35, 7, -1): code, out, err = self.t(self.uuid[0:i] + " list") self.assertIn("one", out) self.assertNotIn("two", out) # TODO This should fail because a 7-character UUID is not a UUID, but # instead it blindly does nothing, and succeeds. Voodoo. - #code, out, err = self.t(self.uuid[0:6] + " list") + # code, out, err = self.t(self.uuid[0:6] + " list") if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/variant_add.test.cpp b/test/variant_add.test.cpp index 8c6f22e9f..1cbd1eb92 100644 --- a/test/variant_add.test.cpp +++ b/test/variant_add.test.cpp @@ -27,213 +27,221 @@ #include // cmake.h include header must come first -#include -#include #include +#include + +#include #define EPSILON 0.001 //////////////////////////////////////////////////////////////////////////////// -int main (int, char**) -{ - UnitTest t (80); +int main(int, char**) { + UnitTest t(80); - Variant v0 (true); - Variant v1 (42); - Variant v2 (3.14); - Variant v3 ("foo"); - Variant v4 (1234567890, Variant::type_date); - Variant v5 (1200, Variant::type_duration); + Variant v0(true); + Variant v1(42); + Variant v2(3.14); + Variant v3("foo"); + Variant v4(1234567890, Variant::type_date); + Variant v5(1200, Variant::type_duration); // boolean + boolean -> ERROR - try {Variant v00 = v0 + v0; t.fail ("true + true --> error");} - catch (...) {t.pass ("true + true --> error");} + try { + Variant v00 = v0 + v0; + t.fail("true + true --> error"); + } catch (...) { + t.pass("true + true --> error"); + } // boolean + integer -> integer Variant v01 = v0 + v1; - t.is (v01.type (), Variant::type_integer, "true + 42 --> integer"); - t.is (v01.get_integer (), 43, "true + 42 --> 43"); + t.is(v01.type(), Variant::type_integer, "true + 42 --> integer"); + t.is(v01.get_integer(), 43, "true + 42 --> 43"); // boolean + real -> real Variant v02 = v0 + v2; - t.is (v02.type (), Variant::type_real, "true + 3.14 --> real"); - t.is (v02.get_real (), 4.14, EPSILON, "true + 3.14 --> 4.14"); + t.is(v02.type(), Variant::type_real, "true + 3.14 --> real"); + t.is(v02.get_real(), 4.14, EPSILON, "true + 3.14 --> 4.14"); // boolean + string -> string Variant v03 = v0 + v3; - t.is (v03.type (), Variant::type_string, "true + foo --> string"); - t.is (v03.get_string (), "truefoo", "true + foo --> truefoo"); + t.is(v03.type(), Variant::type_string, "true + foo --> string"); + t.is(v03.get_string(), "truefoo", "true + foo --> truefoo"); // boolean + date -> date Variant v04 = v0 + v4; - t.is (v04.type (), Variant::type_date, "true + 1234567890 --> date"); - t.is (v04.get_date (), "1234567891", "true + 1234567890 --> 1234567891"); + t.is(v04.type(), Variant::type_date, "true + 1234567890 --> date"); + t.is(v04.get_date(), "1234567891", "true + 1234567890 --> 1234567891"); // boolean + duration -> duration Variant v05 = v0 + v5; - t.is (v05.type (), Variant::type_duration, "true + 1200 --> duration"); - t.is (v05.get_duration (), "1201", "true + 1200 --> 1201"); + t.is(v05.type(), Variant::type_duration, "true + 1200 --> duration"); + t.is(v05.get_duration(), "1201", "true + 1200 --> 1201"); // integer + boolean -> integer Variant v10 = v1 + v0; - t.is (v10.type (), Variant::type_integer, "42 + true --> integer"); - t.is (v10.get_integer (), 43, "42 + true --> 43"); + t.is(v10.type(), Variant::type_integer, "42 + true --> integer"); + t.is(v10.get_integer(), 43, "42 + true --> 43"); // integer + integer -> integer Variant v11 = v1 + v1; - t.is (v11.type (), Variant::type_integer, "42 + 42 --> integer"); - t.is (v11.get_integer (), 84, "42 + 42 --> 84"); + t.is(v11.type(), Variant::type_integer, "42 + 42 --> integer"); + t.is(v11.get_integer(), 84, "42 + 42 --> 84"); // integer + real -> real Variant v12 = v1 + v2; - t.is (v12.type (), Variant::type_real, "42 + 3.14 --> real"); - t.is (v12.get_real (), 45.14, EPSILON, "42 + 3.14 --> 45.14"); + t.is(v12.type(), Variant::type_real, "42 + 3.14 --> real"); + t.is(v12.get_real(), 45.14, EPSILON, "42 + 3.14 --> 45.14"); // integer + string -> string Variant v13 = v1 + v3; - t.is (v13.type (), Variant::type_string, "42 + foo --> string"); - t.is (v13.get_string (), "42foo", "42 + foo --> 42foo"); + t.is(v13.type(), Variant::type_string, "42 + foo --> string"); + t.is(v13.get_string(), "42foo", "42 + foo --> 42foo"); // integer + date -> date Variant v14 = v1 + v4; - t.is (v14.type (), Variant::type_date, "42 + 1234567890 --> date"); - t.is (v14.get_date (), 1234567932, "42 + 1234567890 --> 1234567932"); + t.is(v14.type(), Variant::type_date, "42 + 1234567890 --> date"); + t.is(v14.get_date(), 1234567932, "42 + 1234567890 --> 1234567932"); // integer + duration -> duration Variant v15 = v1 + v5; - t.is (v15.type (), Variant::type_duration, "42 + 1200 --> duration"); - t.is (v15.get_duration (), 1242, "42 + 1200 --> 1242"); + t.is(v15.type(), Variant::type_duration, "42 + 1200 --> duration"); + t.is(v15.get_duration(), 1242, "42 + 1200 --> 1242"); // real + boolean -> real Variant v20 = v2 + v0; - t.is (v20.type (), Variant::type_real, "3.14 + true --> real"); - t.is (v20.get_real (), 4.14, EPSILON, "3.14 + true --> 4.14"); + t.is(v20.type(), Variant::type_real, "3.14 + true --> real"); + t.is(v20.get_real(), 4.14, EPSILON, "3.14 + true --> 4.14"); // real + integer -> real Variant v21 = v2 + v1; - t.is (v21.type (), Variant::type_real, "3.14 + 42 --> real"); - t.is (v21.get_real (), 45.14, EPSILON, "3.14 + 42 --> 45.14"); + t.is(v21.type(), Variant::type_real, "3.14 + 42 --> real"); + t.is(v21.get_real(), 45.14, EPSILON, "3.14 + 42 --> 45.14"); // real + real -> real Variant v22 = v2 + v2; - t.is (v22.type (), Variant::type_real, "3.14 + 3.14 --> real"); - t.is (v22.get_real (), 6.28, EPSILON, "3.14 + 3.14 --> 6.28"); + t.is(v22.type(), Variant::type_real, "3.14 + 3.14 --> real"); + t.is(v22.get_real(), 6.28, EPSILON, "3.14 + 3.14 --> 6.28"); // real + string -> string Variant v23 = v2 + v3; - t.is (v23.type (), Variant::type_string, "3.14 + foo --> string"); - t.is (v23.get_string (), "3.14foo", "3.14 + foo --> 3.14foo"); + t.is(v23.type(), Variant::type_string, "3.14 + foo --> string"); + t.is(v23.get_string(), "3.14foo", "3.14 + foo --> 3.14foo"); // real + date -> date Variant v24 = v2 + v4; - t.is (v24.type (), Variant::type_date, "3.14 + 1234567890 --> date"); - t.is (v24.get_date (), 1234567893, "3.14 + 1234567890 --> 1234567893"); + t.is(v24.type(), Variant::type_date, "3.14 + 1234567890 --> date"); + t.is(v24.get_date(), 1234567893, "3.14 + 1234567890 --> 1234567893"); // real + duration -> duration Variant v25 = v2 + v5; - t.is (v25.type (), Variant::type_duration, "3.14 + 1200 --> duration"); - t.is (v25.get_duration (), 1203, "3.14 + 1200 --> 1203"); + t.is(v25.type(), Variant::type_duration, "3.14 + 1200 --> duration"); + t.is(v25.get_duration(), 1203, "3.14 + 1200 --> 1203"); // string + boolean -> string Variant v30 = v3 + v0; - t.is (v30.type (), Variant::type_string, "foo + true --> string"); - t.is (v30.get_string (), "footrue", "foo + true --> footrue"); + t.is(v30.type(), Variant::type_string, "foo + true --> string"); + t.is(v30.get_string(), "footrue", "foo + true --> footrue"); // string + integer -> string Variant v31 = v3 + v1; - t.is (v31.type (), Variant::type_string, "foo + 42 --> string"); - t.is (v31.get_string (), "foo42", "foo + 42 --> foo42"); + t.is(v31.type(), Variant::type_string, "foo + 42 --> string"); + t.is(v31.get_string(), "foo42", "foo + 42 --> foo42"); // string + real -> string Variant v32 = v3 + v2; - t.is (v32.type (), Variant::type_string, "foo + 3.14 --> string"); - t.is (v32.get_string (), "foo3.14", "foo + 3.14 --> foo3.14"); + t.is(v32.type(), Variant::type_string, "foo + 3.14 --> string"); + t.is(v32.get_string(), "foo3.14", "foo + 3.14 --> foo3.14"); // string + string -> string Variant v33 = v3 + v3; - t.is (v33.type (), Variant::type_string, "foo + foo --> string"); - t.is (v33.get_string (), "foofoo", "foo + foo --> foofoo"); + t.is(v33.type(), Variant::type_string, "foo + foo --> string"); + t.is(v33.get_string(), "foofoo", "foo + foo --> foofoo"); // string + date -> string Variant v34 = v3 + v4; - t.is (v34.type (), Variant::type_string, "foo + 1234567890 --> string"); - std::string s = v34.get_string (); - t.is ((int)s[7], (int)'-', "foo + 1234567890 --> fooYYYY-MM-DDThh:mm:ss"); - t.is ((int)s[10], (int)'-', "foo + 1234567890 --> fooYYYY-MM-DDThh:mm:ss"); - t.is ((int)s[13], (int)'T', "foo + 1234567890 --> fooYYYY-MM-DDThh:mm:ss"); - t.is ((int)s[16], (int)':', "foo + 1234567890 --> fooYYYY-MM-DDThh:mm:ss"); - t.is ((int)s[19], (int)':', "foo + 1234567890 --> fooYYYY-MM-DDThh:mm:ss"); - t.is ((int)s.length (), 22, "foo + 1234567890 --> fooYYYY-MM-DDThh:mm:ss"); + t.is(v34.type(), Variant::type_string, "foo + 1234567890 --> string"); + std::string s = v34.get_string(); + t.is((int)s[7], (int)'-', "foo + 1234567890 --> fooYYYY-MM-DDThh:mm:ss"); + t.is((int)s[10], (int)'-', "foo + 1234567890 --> fooYYYY-MM-DDThh:mm:ss"); + t.is((int)s[13], (int)'T', "foo + 1234567890 --> fooYYYY-MM-DDThh:mm:ss"); + t.is((int)s[16], (int)':', "foo + 1234567890 --> fooYYYY-MM-DDThh:mm:ss"); + t.is((int)s[19], (int)':', "foo + 1234567890 --> fooYYYY-MM-DDThh:mm:ss"); + t.is((int)s.length(), 22, "foo + 1234567890 --> fooYYYY-MM-DDThh:mm:ss"); // string + duration -> string Variant v35 = v3 + v5; - t.is (v35.type (), Variant::type_string, "foo + 1200 --> string"); - t.is (v35.get_string (), "fooPT20M", "foo + 1200 --> fooPT20M"); + t.is(v35.type(), Variant::type_string, "foo + 1200 --> string"); + t.is(v35.get_string(), "fooPT20M", "foo + 1200 --> fooPT20M"); // date + boolean -> date Variant v40 = v4 + v0; - t.is (v40.type (), Variant::type_date, "1234567890 + true --> date"); - t.is (v40.get_date (), 1234567891, "1234567890 + true --> 1234567891"); + t.is(v40.type(), Variant::type_date, "1234567890 + true --> date"); + t.is(v40.get_date(), 1234567891, "1234567890 + true --> 1234567891"); // date + integer -> date Variant v41 = v4 + v1; - t.is (v41.type (), Variant::type_date, "1234567890 + 42 --> date"); - t.is (v41.get_date (), 1234567932, "1234567890 + 42 --> 1234567932"); + t.is(v41.type(), Variant::type_date, "1234567890 + 42 --> date"); + t.is(v41.get_date(), 1234567932, "1234567890 + 42 --> 1234567932"); // date + real -> date Variant v42 = v4 + v2; - t.is (v42.type (), Variant::type_date, "1234567890 + 3.14 --> date"); - t.is (v42.get_date (), 1234567893, "1234567890 + 3.14 --> 1234567893"); + t.is(v42.type(), Variant::type_date, "1234567890 + 3.14 --> date"); + t.is(v42.get_date(), 1234567893, "1234567890 + 3.14 --> 1234567893"); // date + string -> string Variant v43 = v4 + v3; - t.is (v43.type (), Variant::type_string, "1234567890 + foo --> string"); - s = v43.get_string (); - t.is ((int)s[4], (int)'-', "1234567890 + foo --> YYYY-MM-DDThh:mm:ssfoo"); - t.is ((int)s[7], (int)'-', "1234567890 + foo --> YYYY-MM-DDThh:mm:ssfoo"); - t.is ((int)s[10], (int)'T', "1234567890 + foo --> YYYY-MM-DDThh:mm:ssfoo"); - t.is ((int)s[13], (int)':', "1234567890 + foo --> YYYY-MM-DDThh:mm:ssfoo"); - t.is ((int)s[16], (int)':', "1234567890 + foo --> YYYY-MM-DDThh:mm:ssfoo"); - t.is ((int)s.length (), 22, "1234567890 + foo --> YYYY-MM-DDThh:mm:ssfoo"); + t.is(v43.type(), Variant::type_string, "1234567890 + foo --> string"); + s = v43.get_string(); + t.is((int)s[4], (int)'-', "1234567890 + foo --> YYYY-MM-DDThh:mm:ssfoo"); + t.is((int)s[7], (int)'-', "1234567890 + foo --> YYYY-MM-DDThh:mm:ssfoo"); + t.is((int)s[10], (int)'T', "1234567890 + foo --> YYYY-MM-DDThh:mm:ssfoo"); + t.is((int)s[13], (int)':', "1234567890 + foo --> YYYY-MM-DDThh:mm:ssfoo"); + t.is((int)s[16], (int)':', "1234567890 + foo --> YYYY-MM-DDThh:mm:ssfoo"); + t.is((int)s.length(), 22, "1234567890 + foo --> YYYY-MM-DDThh:mm:ssfoo"); // date + date -> ERROR - try {Variant v44 = v4 + v4; t.fail ("1234567890 + 1234567890 --> error");} - catch (...) {t.pass ("1234567890 + 1234567890 --> error");} + try { + Variant v44 = v4 + v4; + t.fail("1234567890 + 1234567890 --> error"); + } catch (...) { + t.pass("1234567890 + 1234567890 --> error"); + } // date + duration -> date Variant v45 = v4 + v5; - t.is (v45.type (), Variant::type_date, "1234567890 + 1200 --> date"); - t.is (v45.get_date (), 1234569090, "1234567890 + 1200 --> 1234569090"); + t.is(v45.type(), Variant::type_date, "1234567890 + 1200 --> date"); + t.is(v45.get_date(), 1234569090, "1234567890 + 1200 --> 1234569090"); // duration + boolean -> duration Variant v50 = v5 + v0; - t.is (v50.type (), Variant::type_duration, "1200 + true --> duration"); - t.is (v50.get_duration (), 1201, "1200 + true --> 1201"); + t.is(v50.type(), Variant::type_duration, "1200 + true --> duration"); + t.is(v50.get_duration(), 1201, "1200 + true --> 1201"); // duration + integer -> duration Variant v51 = v5 + v1; - t.is (v51.type (), Variant::type_duration, "1200 + 42 --> duration"); - t.is (v51.get_duration (), 1242, "1200 + 42 --> 1242"); + t.is(v51.type(), Variant::type_duration, "1200 + 42 --> duration"); + t.is(v51.get_duration(), 1242, "1200 + 42 --> 1242"); // duration + real -> duration Variant v52 = v5 + v2; - t.is (v52.type (), Variant::type_duration, "1200 + 3.14 --> duration"); - t.is (v52.get_duration (), 1203, "1200 + 3.14 --> 1203"); + t.is(v52.type(), Variant::type_duration, "1200 + 3.14 --> duration"); + t.is(v52.get_duration(), 1203, "1200 + 3.14 --> 1203"); // duration + string -> string Variant v53 = v5 + v3; - t.is (v53.type (), Variant::type_string, "1200 + foo --> string"); - t.is (v53.get_string (), "PT20Mfoo", "1200 + foo --> PT20Mfoo"); + t.is(v53.type(), Variant::type_string, "1200 + foo --> string"); + t.is(v53.get_string(), "PT20Mfoo", "1200 + foo --> PT20Mfoo"); // duration + date -> date Variant v54 = v5 + v4; - t.is (v54.type (), Variant::type_date, "1200 + 1234567890 --> date"); - t.is (v54.get_date (), 1234569090, "1200 + 1234567890 --> 1234569090"); + t.is(v54.type(), Variant::type_date, "1200 + 1234567890 --> date"); + t.is(v54.get_date(), 1234569090, "1200 + 1234567890 --> 1234569090"); // duration + duration -> duration Variant v55 = v5 + v5; - t.is (v55.type (), Variant::type_duration, "1200 + 1200 --> duration"); - t.is (v55.get_duration (), 2400, "1200 + 1200 --> 2400"); + t.is(v55.type(), Variant::type_duration, "1200 + 1200 --> duration"); + t.is(v55.get_duration(), 2400, "1200 + 1200 --> 2400"); return 0; } diff --git a/test/variant_and.test.cpp b/test/variant_and.test.cpp index 237bbd02d..78267656b 100644 --- a/test/variant_and.test.cpp +++ b/test/variant_and.test.cpp @@ -27,173 +27,173 @@ #include // cmake.h include header must come first -#include -#include #include +#include + +#include //////////////////////////////////////////////////////////////////////////////// -int main (int, char**) -{ - UnitTest t (76); +int main(int, char**) { + UnitTest t(76); - Variant v0 (true); - Variant v1 (42); - Variant v2 (3.14); - Variant v3 ("foo"); - Variant v4 (1234567890, Variant::type_date); - Variant v5 (1200, Variant::type_duration); + Variant v0(true); + Variant v1(42); + Variant v2(3.14); + Variant v3("foo"); + Variant v4(1234567890, Variant::type_date); + Variant v5(1200, Variant::type_duration); // Truth table. - Variant vFalse (false); - Variant vTrue (true); - t.is (vFalse && vFalse, false, "false && false --> false"); - t.is (vFalse && vTrue, false, "false && true --> false"); - t.is (vTrue && vFalse, false, "true && false --> false"); - t.is (vTrue && vTrue, true, "true && true --> true"); + Variant vFalse(false); + Variant vTrue(true); + t.is(vFalse && vFalse, false, "false && false --> false"); + t.is(vFalse && vTrue, false, "false && true --> false"); + t.is(vTrue && vFalse, false, "true && false --> false"); + t.is(vTrue && vTrue, true, "true && true --> true"); Variant v00 = v0 && v0; - t.is (v00.type (), Variant::type_boolean, "true && true --> boolean"); - t.is (v00.get_bool (), true, "true && true --> true"); + t.is(v00.type(), Variant::type_boolean, "true && true --> boolean"); + t.is(v00.get_bool(), true, "true && true --> true"); Variant v01 = v0 && v1; - t.is (v01.type (), Variant::type_boolean, "true && 42 --> boolean"); - t.is (v01.get_bool (), true, "true && 42 --> true"); + t.is(v01.type(), Variant::type_boolean, "true && 42 --> boolean"); + t.is(v01.get_bool(), true, "true && 42 --> true"); Variant v02 = v0 && v2; - t.is (v02.type (), Variant::type_boolean, "true && 3.14 --> boolean"); - t.is (v02.get_bool (), true, "true && 3.14 --> true"); + t.is(v02.type(), Variant::type_boolean, "true && 3.14 --> boolean"); + t.is(v02.get_bool(), true, "true && 3.14 --> true"); Variant v03 = v0 && v3; - t.is (v03.type (), Variant::type_boolean, "true && 'foo' --> boolean"); - t.is (v03.get_bool (), true, "true && 'foo' --> true"); + t.is(v03.type(), Variant::type_boolean, "true && 'foo' --> boolean"); + t.is(v03.get_bool(), true, "true && 'foo' --> true"); Variant v04 = v0 && v4; - t.is (v04.type (), Variant::type_boolean, "true && 1234567890 --> boolean"); - t.is (v04.get_bool (), true, "true && 1234567890 --> true"); + t.is(v04.type(), Variant::type_boolean, "true && 1234567890 --> boolean"); + t.is(v04.get_bool(), true, "true && 1234567890 --> true"); Variant v05 = v0 && v5; - t.is (v05.type (), Variant::type_boolean, "true && 1200 --> boolean"); - t.is (v05.get_bool (), true, "true && 1200 --> true"); + t.is(v05.type(), Variant::type_boolean, "true && 1200 --> boolean"); + t.is(v05.get_bool(), true, "true && 1200 --> true"); Variant v10 = v1 && v0; - t.is (v10.type (), Variant::type_boolean, "42 && true --> boolean"); - t.is (v10.get_bool (), true, "42 && true --> true"); + t.is(v10.type(), Variant::type_boolean, "42 && true --> boolean"); + t.is(v10.get_bool(), true, "42 && true --> true"); Variant v11 = v1 && v1; - t.is (v11.type (), Variant::type_boolean, "42 && 42 --> boolean"); - t.is (v11.get_bool (), true, "42 && 42 --> true"); + t.is(v11.type(), Variant::type_boolean, "42 && 42 --> boolean"); + t.is(v11.get_bool(), true, "42 && 42 --> true"); Variant v12 = v1 && v2; - t.is (v12.type (), Variant::type_boolean, "42 && 3.14 --> boolean"); - t.is (v12.get_bool (), true, "42 && 3.14 --> true"); + t.is(v12.type(), Variant::type_boolean, "42 && 3.14 --> boolean"); + t.is(v12.get_bool(), true, "42 && 3.14 --> true"); Variant v13 = v1 && v3; - t.is (v13.type (), Variant::type_boolean, "42 && 'foo' --> boolean"); - t.is (v13.get_bool (), true, "42 && 'foo' --> true"); + t.is(v13.type(), Variant::type_boolean, "42 && 'foo' --> boolean"); + t.is(v13.get_bool(), true, "42 && 'foo' --> true"); Variant v14 = v1 && v4; - t.is (v04.type (), Variant::type_boolean, "42 && 1234567890 --> boolean"); - t.is (v04.get_bool (), true, "42 && 1234567890 --> true"); + t.is(v04.type(), Variant::type_boolean, "42 && 1234567890 --> boolean"); + t.is(v04.get_bool(), true, "42 && 1234567890 --> true"); Variant v15 = v1 && v5; - t.is (v15.type (), Variant::type_boolean, "42 && 1200 --> boolean"); - t.is (v15.get_bool (), true, "42 && 1200 --> true"); + t.is(v15.type(), Variant::type_boolean, "42 && 1200 --> boolean"); + t.is(v15.get_bool(), true, "42 && 1200 --> true"); Variant v20 = v2 && v0; - t.is (v20.type (), Variant::type_boolean, "3.14 && true --> boolean"); - t.is (v20.get_bool (), true, "3.14 && true --> true"); + t.is(v20.type(), Variant::type_boolean, "3.14 && true --> boolean"); + t.is(v20.get_bool(), true, "3.14 && true --> true"); Variant v21 = v2 && v1; - t.is (v21.type (), Variant::type_boolean, "3.14 && 42 --> boolean"); - t.is (v21.get_bool (), true, "3.14 && 42 --> true"); + t.is(v21.type(), Variant::type_boolean, "3.14 && 42 --> boolean"); + t.is(v21.get_bool(), true, "3.14 && 42 --> true"); Variant v22 = v2 && v2; - t.is (v22.type (), Variant::type_boolean, "3.14 && 3.14 --> boolean"); - t.is (v22.get_bool (), true, "3.14 && 3.14 --> true"); + t.is(v22.type(), Variant::type_boolean, "3.14 && 3.14 --> boolean"); + t.is(v22.get_bool(), true, "3.14 && 3.14 --> true"); Variant v23 = v2 && v3; - t.is (v23.type (), Variant::type_boolean, "3.14 && 'foo' --> boolean"); - t.is (v23.get_bool (), true, "3.14 && 'foo' --> true"); + t.is(v23.type(), Variant::type_boolean, "3.14 && 'foo' --> boolean"); + t.is(v23.get_bool(), true, "3.14 && 'foo' --> true"); Variant v24 = v2 && v4; - t.is (v24.type (), Variant::type_boolean, "3.14 && 1234567890 --> boolean"); - t.is (v24.get_bool (), true, "3.14 && 1234567890 --> true"); + t.is(v24.type(), Variant::type_boolean, "3.14 && 1234567890 --> boolean"); + t.is(v24.get_bool(), true, "3.14 && 1234567890 --> true"); Variant v25 = v2 && v5; - t.is (v25.type (), Variant::type_boolean, "3.14 && 1200 --> boolean"); - t.is (v25.get_bool (), true, "3.14 && 1200 --> true"); + t.is(v25.type(), Variant::type_boolean, "3.14 && 1200 --> boolean"); + t.is(v25.get_bool(), true, "3.14 && 1200 --> true"); Variant v30 = v3 && v0; - t.is (v30.type (), Variant::type_boolean, "'foo' && true --> boolean"); - t.is (v30.get_bool (), true, "'foo' && true --> true"); + t.is(v30.type(), Variant::type_boolean, "'foo' && true --> boolean"); + t.is(v30.get_bool(), true, "'foo' && true --> true"); Variant v31 = v3 && v1; - t.is (v31.type (), Variant::type_boolean, "'foo' && 42 --> boolean"); - t.is (v31.get_bool (), true, "'foo' && 42 --> true"); + t.is(v31.type(), Variant::type_boolean, "'foo' && 42 --> boolean"); + t.is(v31.get_bool(), true, "'foo' && 42 --> true"); Variant v32 = v3 && v2; - t.is (v32.type (), Variant::type_boolean, "'foo' && 3.14 --> boolean"); - t.is (v32.get_bool (), true, "'foo' && 3.14 --> true"); + t.is(v32.type(), Variant::type_boolean, "'foo' && 3.14 --> boolean"); + t.is(v32.get_bool(), true, "'foo' && 3.14 --> true"); Variant v33 = v3 && v3; - t.is (v33.type (), Variant::type_boolean, "'foo' && 'foo' --> boolean"); - t.is (v33.get_bool (), true, "'foo' && 'foo' --> true"); + t.is(v33.type(), Variant::type_boolean, "'foo' && 'foo' --> boolean"); + t.is(v33.get_bool(), true, "'foo' && 'foo' --> true"); Variant v34 = v3 && v4; - t.is (v34.type (), Variant::type_boolean, "'foo' && 1234567890 --> boolean"); - t.is (v34.get_bool (), true, "'foo' && 1234567890 --> true"); + t.is(v34.type(), Variant::type_boolean, "'foo' && 1234567890 --> boolean"); + t.is(v34.get_bool(), true, "'foo' && 1234567890 --> true"); Variant v35 = v3 && v5; - t.is (v35.type (), Variant::type_boolean, "'foo' && 1200 --> boolean"); - t.is (v35.get_bool (), true, "'foo' && 1200 --> true"); + t.is(v35.type(), Variant::type_boolean, "'foo' && 1200 --> boolean"); + t.is(v35.get_bool(), true, "'foo' && 1200 --> true"); Variant v40 = v4 && v0; - t.is (v40.type (), Variant::type_boolean, "1234567890 && true --> boolean"); - t.is (v40.get_bool (), true, "1234567890 && true --> true"); + t.is(v40.type(), Variant::type_boolean, "1234567890 && true --> boolean"); + t.is(v40.get_bool(), true, "1234567890 && true --> true"); Variant v41 = v4 && v1; - t.is (v41.type (), Variant::type_boolean, "1234567890 && 42 --> boolean"); - t.is (v41.get_bool (), true, "1234567890 && 42 --> true"); + t.is(v41.type(), Variant::type_boolean, "1234567890 && 42 --> boolean"); + t.is(v41.get_bool(), true, "1234567890 && 42 --> true"); Variant v42 = v4 && v2; - t.is (v42.type (), Variant::type_boolean, "1234567890 && 3.14 --> boolean"); - t.is (v42.get_bool (), true, "1234567890 && 3.14 --> true"); + t.is(v42.type(), Variant::type_boolean, "1234567890 && 3.14 --> boolean"); + t.is(v42.get_bool(), true, "1234567890 && 3.14 --> true"); Variant v43 = v4 && v3; - t.is (v43.type (), Variant::type_boolean, "1234567890 && 'foo' --> boolean"); - t.is (v43.get_bool (), true, "1234567890 && 'foo' --> true"); + t.is(v43.type(), Variant::type_boolean, "1234567890 && 'foo' --> boolean"); + t.is(v43.get_bool(), true, "1234567890 && 'foo' --> true"); Variant v44 = v4 && v4; - t.is (v44.type (), Variant::type_boolean, "1234567890 && 1234567890 --> boolean"); - t.is (v44.get_bool (), true, "1234567890 && 1234567890 --> true"); + t.is(v44.type(), Variant::type_boolean, "1234567890 && 1234567890 --> boolean"); + t.is(v44.get_bool(), true, "1234567890 && 1234567890 --> true"); Variant v45 = v4 && v5; - t.is (v45.type (), Variant::type_boolean, "1234567890 && 1200 --> boolean"); - t.is (v45.get_bool (), true, "1234567890 && 1200 --> true"); + t.is(v45.type(), Variant::type_boolean, "1234567890 && 1200 --> boolean"); + t.is(v45.get_bool(), true, "1234567890 && 1200 --> true"); Variant v50 = v5 && v0; - t.is (v50.type (), Variant::type_boolean, "1200 && true --> boolean"); - t.is (v50.get_bool (), true, "1200 && true --> true"); + t.is(v50.type(), Variant::type_boolean, "1200 && true --> boolean"); + t.is(v50.get_bool(), true, "1200 && true --> true"); Variant v51 = v5 && v1; - t.is (v51.type (), Variant::type_boolean, "1200 && 42 --> boolean"); - t.is (v51.get_bool (), true, "1200 && 42 --> true"); + t.is(v51.type(), Variant::type_boolean, "1200 && 42 --> boolean"); + t.is(v51.get_bool(), true, "1200 && 42 --> true"); Variant v52 = v5 && v2; - t.is (v52.type (), Variant::type_boolean, "1200 && 3.14 --> boolean"); - t.is (v52.get_bool (), true, "1200 && 3.14 --> true"); + t.is(v52.type(), Variant::type_boolean, "1200 && 3.14 --> boolean"); + t.is(v52.get_bool(), true, "1200 && 3.14 --> true"); Variant v53 = v5 && v3; - t.is (v53.type (), Variant::type_boolean, "1200 && 'foo' --> boolean"); - t.is (v53.get_bool (), true, "1200 && 'foo' --> true"); + t.is(v53.type(), Variant::type_boolean, "1200 && 'foo' --> boolean"); + t.is(v53.get_bool(), true, "1200 && 'foo' --> true"); Variant v54 = v5 && v4; - t.is (v04.type (), Variant::type_boolean, "1200 && 1234567890 --> boolean"); - t.is (v04.get_bool (), true, "1200 && 1234567890 --> true"); + t.is(v04.type(), Variant::type_boolean, "1200 && 1234567890 --> boolean"); + t.is(v04.get_bool(), true, "1200 && 1234567890 --> true"); Variant v55 = v5 && v5; - t.is (v55.type (), Variant::type_boolean, "1200 && 1200 --> boolean"); - t.is (v55.get_bool (), true, "1200 && 1200 --> true"); + t.is(v55.type(), Variant::type_boolean, "1200 && 1200 --> boolean"); + t.is(v55.get_bool(), true, "1200 && 1200 --> true"); return 0; } diff --git a/test/variant_cast.test.cpp b/test/variant_cast.test.cpp index ac6c246ca..e93a82ac6 100644 --- a/test/variant_cast.test.cpp +++ b/test/variant_cast.test.cpp @@ -27,232 +27,230 @@ #include // cmake.h include header must come first -#include -#include #include +#include + +#include #define EPSILON 0.001 //////////////////////////////////////////////////////////////////////////////// -int main (int, char**) -{ - UnitTest t (81); +int main(int, char**) { + UnitTest t(81); - time_t now = time (nullptr); + time_t now = time(nullptr); - try - { + try { // Variant::type_boolean --> * - Variant v00 (true); - v00.cast (Variant::type_boolean); - t.ok (v00.type () == Variant::type_boolean, "cast boolean --> boolean"); - t.ok (v00.get_bool () == true, "cast boolean --> boolean"); + Variant v00(true); + v00.cast(Variant::type_boolean); + t.ok(v00.type() == Variant::type_boolean, "cast boolean --> boolean"); + t.ok(v00.get_bool() == true, "cast boolean --> boolean"); - Variant v01 (true); - v01.cast (Variant::type_integer); - t.ok (v01.type () == Variant::type_integer, "cast boolean --> integer"); - t.ok (v01.get_integer () == 1, "cast boolean --> integer"); + Variant v01(true); + v01.cast(Variant::type_integer); + t.ok(v01.type() == Variant::type_integer, "cast boolean --> integer"); + t.ok(v01.get_integer() == 1, "cast boolean --> integer"); - Variant v02 (true); - v02.cast (Variant::type_real); - t.ok (v02.type () == Variant::type_real, "cast boolean --> real"); - t.is (v02.get_real (), 1.0, EPSILON, "cast boolean --> real"); + Variant v02(true); + v02.cast(Variant::type_real); + t.ok(v02.type() == Variant::type_real, "cast boolean --> real"); + t.is(v02.get_real(), 1.0, EPSILON, "cast boolean --> real"); - Variant v03 (true); - v03.cast (Variant::type_string); - t.ok (v03.type () == Variant::type_string, "cast boolean --> string"); - t.ok (v03.get_string () == "true", "cast boolean --> string"); + Variant v03(true); + v03.cast(Variant::type_string); + t.ok(v03.type() == Variant::type_string, "cast boolean --> string"); + t.ok(v03.get_string() == "true", "cast boolean --> string"); - Variant v04 (true); - v04.cast (Variant::type_date); - t.ok (v04.type () == Variant::type_date, "cast boolean --> date"); - t.is (v04.get_date (), 1, "cast boolean --> date"); + Variant v04(true); + v04.cast(Variant::type_date); + t.ok(v04.type() == Variant::type_date, "cast boolean --> date"); + t.is(v04.get_date(), 1, "cast boolean --> date"); - Variant v05 (true); - v05.cast (Variant::type_duration); - t.ok (v05.type () == Variant::type_duration, "cast boolean --> duration"); - t.is (v05.get_duration (), 1, "cast boolean --> duration"); + Variant v05(true); + v05.cast(Variant::type_duration); + t.ok(v05.type() == Variant::type_duration, "cast boolean --> duration"); + t.is(v05.get_duration(), 1, "cast boolean --> duration"); // Variant::type_integer --> * - Variant v10 (42); - v10.cast (Variant::type_boolean); - t.ok (v10.type () == Variant::type_boolean, "cast integer --> boolean"); - t.ok (v10.get_bool () == true, "cast integer --> boolean"); + Variant v10(42); + v10.cast(Variant::type_boolean); + t.ok(v10.type() == Variant::type_boolean, "cast integer --> boolean"); + t.ok(v10.get_bool() == true, "cast integer --> boolean"); - Variant v11 (42); - v11.cast (Variant::type_integer); - t.ok (v11.type () == Variant::type_integer, "cast integer --> integer"); - t.ok (v11.get_integer () == 42, "cast integer --> integer"); + Variant v11(42); + v11.cast(Variant::type_integer); + t.ok(v11.type() == Variant::type_integer, "cast integer --> integer"); + t.ok(v11.get_integer() == 42, "cast integer --> integer"); - Variant v12 (42); - v12.cast (Variant::type_real); - t.ok (v12.type () == Variant::type_real, "cast integer --> real"); - t.is (v12.get_real (), 42.0, EPSILON, "cast integer --> real"); + Variant v12(42); + v12.cast(Variant::type_real); + t.ok(v12.type() == Variant::type_real, "cast integer --> real"); + t.is(v12.get_real(), 42.0, EPSILON, "cast integer --> real"); - Variant v13 (42); - v13.cast (Variant::type_string); - t.is (v13.type (), Variant::type_string, "cast integer --> string"); - t.is (v13.get_string (), "42", "cast integer --> string"); + Variant v13(42); + v13.cast(Variant::type_string); + t.is(v13.type(), Variant::type_string, "cast integer --> string"); + t.is(v13.get_string(), "42", "cast integer --> string"); - Variant v14 (42); - v14.cast (Variant::type_date); - t.ok (v14.type () == Variant::type_date, "cast integer --> date"); - t.ok (v14.get_date () == 42, "cast integer --> date"); + Variant v14(42); + v14.cast(Variant::type_date); + t.ok(v14.type() == Variant::type_date, "cast integer --> date"); + t.ok(v14.get_date() == 42, "cast integer --> date"); - Variant v15 (42); - v15.cast (Variant::type_duration); - t.is (v15.type (), Variant::type_duration, "cast integer --> duration"); - t.is (v15.get_duration (), 42, "cast integer --> duration"); + Variant v15(42); + v15.cast(Variant::type_duration); + t.is(v15.type(), Variant::type_duration, "cast integer --> duration"); + t.is(v15.get_duration(), 42, "cast integer --> duration"); // Variant::type_real --> * - Variant v20 (3.14); - v20.cast (Variant::type_boolean); - t.ok (v20.type () == Variant::type_boolean, "cast real --> boolean"); - t.ok (v20.get_bool () == true, "cast real --> boolean"); + Variant v20(3.14); + v20.cast(Variant::type_boolean); + t.ok(v20.type() == Variant::type_boolean, "cast real --> boolean"); + t.ok(v20.get_bool() == true, "cast real --> boolean"); - Variant v21 (3.14); - v21.cast (Variant::type_integer); - t.ok (v21.type () == Variant::type_integer, "cast real --> integer"); - t.ok (v21.get_integer () == 3, "cast real --> integer"); + Variant v21(3.14); + v21.cast(Variant::type_integer); + t.ok(v21.type() == Variant::type_integer, "cast real --> integer"); + t.ok(v21.get_integer() == 3, "cast real --> integer"); - Variant v22 (3.14); - v22.cast (Variant::type_real); - t.ok (v22.type () == Variant::type_real, "cast real --> real"); - t.is (v22.get_real (), 3.14, EPSILON, "cast real --> real"); + Variant v22(3.14); + v22.cast(Variant::type_real); + t.ok(v22.type() == Variant::type_real, "cast real --> real"); + t.is(v22.get_real(), 3.14, EPSILON, "cast real --> real"); - Variant v23 (3.14); - v23.cast (Variant::type_string); - t.ok (v23.type () == Variant::type_string, "cast real --> string"); - t.ok (v23.get_string () == "3.14", "cast real --> string"); + Variant v23(3.14); + v23.cast(Variant::type_string); + t.ok(v23.type() == Variant::type_string, "cast real --> string"); + t.ok(v23.get_string() == "3.14", "cast real --> string"); - Variant v24 (3.14); - v24.cast (Variant::type_date); - t.ok (v24.type () == Variant::type_date, "cast real --> date"); - t.ok (v24.get_date () == 3, "cast real --> date"); + Variant v24(3.14); + v24.cast(Variant::type_date); + t.ok(v24.type() == Variant::type_date, "cast real --> date"); + t.ok(v24.get_date() == 3, "cast real --> date"); - Variant v25 (3.14); - v25.cast (Variant::type_duration); - t.ok (v25.type () == Variant::type_duration, "cast real --> duration"); - t.ok (v25.get_duration () == 3, "cast real --> duration"); + Variant v25(3.14); + v25.cast(Variant::type_duration); + t.ok(v25.type() == Variant::type_duration, "cast real --> duration"); + t.ok(v25.get_duration() == 3, "cast real --> duration"); // Variant::type_string --> * - Variant v30 ("foo"); - v30.cast (Variant::type_boolean); - t.ok (v30.type () == Variant::type_boolean, "cast string --> boolean"); - t.ok (v30.get_bool () == true, "cast string --> boolean"); + Variant v30("foo"); + v30.cast(Variant::type_boolean); + t.ok(v30.type() == Variant::type_boolean, "cast string --> boolean"); + t.ok(v30.get_bool() == true, "cast string --> boolean"); - Variant v31 ("42"); - v31.cast (Variant::type_integer); - t.ok (v31.type () == Variant::type_integer, "cast string --> integer"); - t.ok (v31.get_integer () == 42, "cast string --> integer"); + Variant v31("42"); + v31.cast(Variant::type_integer); + t.ok(v31.type() == Variant::type_integer, "cast string --> integer"); + t.ok(v31.get_integer() == 42, "cast string --> integer"); - Variant v31h ("0x20"); - v31h.cast (Variant::type_integer); - t.ok (v31h.type () == Variant::type_integer, "cast string(hex) --> integer"); - t.ok (v31h.get_integer () == 32, "cast string(hex) --> integer"); + Variant v31h("0x20"); + v31h.cast(Variant::type_integer); + t.ok(v31h.type() == Variant::type_integer, "cast string(hex) --> integer"); + t.ok(v31h.get_integer() == 32, "cast string(hex) --> integer"); - Variant v32 ("3.14"); - v32.cast (Variant::type_real); - t.ok (v32.type () == Variant::type_real, "cast string --> real"); - t.is (v32.get_real (), 3.14, EPSILON, "cast string --> real"); + Variant v32("3.14"); + v32.cast(Variant::type_real); + t.ok(v32.type() == Variant::type_real, "cast string --> real"); + t.is(v32.get_real(), 3.14, EPSILON, "cast string --> real"); - Variant v33 ("foo"); - v33.cast (Variant::type_string); - t.ok (v33.type () == Variant::type_string, "cast string --> string"); - t.ok (v33.get_string () == "foo", "cast string --> string"); + Variant v33("foo"); + v33.cast(Variant::type_string); + t.ok(v33.type() == Variant::type_string, "cast string --> string"); + t.ok(v33.get_string() == "foo", "cast string --> string"); - Variant v34 ("2013-12-07T16:33:00-05:00"); - v34.cast (Variant::type_date); - t.ok (v34.type () == Variant::type_date, "cast string --> date"); - t.ok (v34.get_date () == 1386451980, "cast string --> date"); + Variant v34("2013-12-07T16:33:00-05:00"); + v34.cast(Variant::type_date); + t.ok(v34.type() == Variant::type_date, "cast string --> date"); + t.ok(v34.get_date() == 1386451980, "cast string --> date"); - Variant v35 ("42 days"); - v35.cast (Variant::type_duration); - t.ok (v35.type () == Variant::type_duration, "cast string --> duration"); - t.is (v35.get_duration (), 3628800, "cast string --> duration"); + Variant v35("42 days"); + v35.cast(Variant::type_duration); + t.ok(v35.type() == Variant::type_duration, "cast string --> duration"); + t.is(v35.get_duration(), 3628800, "cast string --> duration"); - Variant v35b ("P42D"); - v35b.cast (Variant::type_duration); - t.ok (v35b.type () == Variant::type_duration, "cast string --> duration"); - t.is (v35b.get_duration (), 3628800, "cast string --> duration"); + Variant v35b("P42D"); + v35b.cast(Variant::type_duration); + t.ok(v35b.type() == Variant::type_duration, "cast string --> duration"); + t.is(v35b.get_duration(), 3628800, "cast string --> duration"); // Variant::type_date --> * - Variant v40 ((time_t) 1234567890, Variant::type_date); - v40.cast (Variant::type_boolean); - t.ok (v40.type () == Variant::type_boolean, "cast date --> boolean"); - t.ok (v40.get_bool () == true, "cast date --> boolean"); + Variant v40((time_t)1234567890, Variant::type_date); + v40.cast(Variant::type_boolean); + t.ok(v40.type() == Variant::type_boolean, "cast date --> boolean"); + t.ok(v40.get_bool() == true, "cast date --> boolean"); - Variant v41 ((time_t) 1234567890, Variant::type_date); - v41.cast (Variant::type_integer); - t.ok (v41.type () == Variant::type_integer, "cast date --> integer"); - t.ok (v41.get_integer () == 1234567890, "cast date --> integer"); + Variant v41((time_t)1234567890, Variant::type_date); + v41.cast(Variant::type_integer); + t.ok(v41.type() == Variant::type_integer, "cast date --> integer"); + t.ok(v41.get_integer() == 1234567890, "cast date --> integer"); - Variant v42 ((time_t) 1234567890, Variant::type_date); - v42.cast (Variant::type_real); - t.ok (v42.type () == Variant::type_real, "cast date --> real"); - t.is (v42.get_real (), 1234567890.0, EPSILON, "cast date --> real"); + Variant v42((time_t)1234567890, Variant::type_date); + v42.cast(Variant::type_real); + t.ok(v42.type() == Variant::type_real, "cast date --> real"); + t.is(v42.get_real(), 1234567890.0, EPSILON, "cast date --> real"); // YYYY-MM-DDThh:mm:ss // ^ ^ ^ ^ ^ - Variant v43 ((time_t) 1234567890, Variant::type_date); - v43.cast (Variant::type_string); - t.ok (v43.type () == Variant::type_string, "cast date --> string"); - std::string s = v43.get_string (); - t.is ((int)s[4], (int)'-', "cast date --> string"); - t.is ((int)s[7], (int)'-', "cast date --> string"); - t.is ((int)s[10], (int)'T', "cast date --> string"); - t.is ((int)s[13], (int)':', "cast date --> string"); - t.is ((int)s[16], (int)':', "cast date --> string"); - t.is ((int)s.length (), 19, "cast date --> string"); + Variant v43((time_t)1234567890, Variant::type_date); + v43.cast(Variant::type_string); + t.ok(v43.type() == Variant::type_string, "cast date --> string"); + std::string s = v43.get_string(); + t.is((int)s[4], (int)'-', "cast date --> string"); + t.is((int)s[7], (int)'-', "cast date --> string"); + t.is((int)s[10], (int)'T', "cast date --> string"); + t.is((int)s[13], (int)':', "cast date --> string"); + t.is((int)s[16], (int)':', "cast date --> string"); + t.is((int)s.length(), 19, "cast date --> string"); - Variant v44 ((time_t) 1234567890, Variant::type_date); - v44.cast (Variant::type_date); - t.ok (v44.type () == Variant::type_date, "cast date --> date"); - t.ok (v44.get_date () == 1234567890, "cast date --> date"); + Variant v44((time_t)1234567890, Variant::type_date); + v44.cast(Variant::type_date); + t.ok(v44.type() == Variant::type_date, "cast date --> date"); + t.ok(v44.get_date() == 1234567890, "cast date --> date"); - Variant v45 ((time_t) 1234567890, Variant::type_date); - v45.cast (Variant::type_duration); - t.ok (v45.type () == Variant::type_duration, "cast date --> duration"); - t.ok (v45.get_duration () <= 1234567890 - now, "cast date --> duration"); + Variant v45((time_t)1234567890, Variant::type_date); + v45.cast(Variant::type_duration); + t.ok(v45.type() == Variant::type_duration, "cast date --> duration"); + t.ok(v45.get_duration() <= 1234567890 - now, "cast date --> duration"); // Assuming this unit test takes less than 10 min to execute - t.ok (v45.get_duration () > 1234567890 - now - 600, "cast date --> duration"); + t.ok(v45.get_duration() > 1234567890 - now - 600, "cast date --> duration"); // Variant::type_duration --> * - Variant v50 ((time_t) 12345, Variant::type_duration); - v50.cast (Variant::type_boolean); - t.ok (v50.type () == Variant::type_boolean, "cast duration --> boolean"); - t.ok (v50.get_bool () == true, "cast duration --> boolean"); + Variant v50((time_t)12345, Variant::type_duration); + v50.cast(Variant::type_boolean); + t.ok(v50.type() == Variant::type_boolean, "cast duration --> boolean"); + t.ok(v50.get_bool() == true, "cast duration --> boolean"); - Variant v51 ((time_t) 12345, Variant::type_duration); - v51.cast (Variant::type_integer); - t.ok (v51.type () == Variant::type_integer, "cast duration --> integer"); - t.ok (v51.get_integer () == 12345, "cast duration --> integer"); + Variant v51((time_t)12345, Variant::type_duration); + v51.cast(Variant::type_integer); + t.ok(v51.type() == Variant::type_integer, "cast duration --> integer"); + t.ok(v51.get_integer() == 12345, "cast duration --> integer"); - Variant v52 ((time_t) 12345, Variant::type_duration); - v52.cast (Variant::type_real); - t.ok (v52.type () == Variant::type_real, "cast duration --> real"); - t.is (v52.get_real (), 12345.0, EPSILON, "cast duration --> real"); + Variant v52((time_t)12345, Variant::type_duration); + v52.cast(Variant::type_real); + t.ok(v52.type() == Variant::type_real, "cast duration --> real"); + t.is(v52.get_real(), 12345.0, EPSILON, "cast duration --> real"); - Variant v53 ((time_t) 12345, Variant::type_duration); - v53.cast (Variant::type_string); - t.ok (v53.type () == Variant::type_string, "cast duration --> string"); - t.is (v53.get_string (), "PT3H25M45S", "cast duration --> string"); + Variant v53((time_t)12345, Variant::type_duration); + v53.cast(Variant::type_string); + t.ok(v53.type() == Variant::type_string, "cast duration --> string"); + t.is(v53.get_string(), "PT3H25M45S", "cast duration --> string"); - Variant v54 ((time_t) 12345, Variant::type_duration); - v54.cast (Variant::type_date); - t.ok (v54.type () == Variant::type_date, "cast duration --> date"); - t.ok (v54.get_date () >= 12345 + now, "cast duration --> duration"); - t.ok (v54.get_date () < 12345 + now + 600, "cast duration --> duration"); + Variant v54((time_t)12345, Variant::type_duration); + v54.cast(Variant::type_date); + t.ok(v54.type() == Variant::type_date, "cast duration --> date"); + t.ok(v54.get_date() >= 12345 + now, "cast duration --> duration"); + t.ok(v54.get_date() < 12345 + now + 600, "cast duration --> duration"); - Variant v55 ((time_t) 12345, Variant::type_duration); - v55.cast (Variant::type_duration); - t.ok (v55.type () == Variant::type_duration, "cast duration --> duration"); - t.is (v55.get_duration (), 12345, "cast duration --> duration"); + Variant v55((time_t)12345, Variant::type_duration); + v55.cast(Variant::type_duration); + t.ok(v55.type() == Variant::type_duration, "cast duration --> duration"); + t.is(v55.get_duration(), 12345, "cast duration --> duration"); } - catch (const std::string& e) - { - t.diag (e); + catch (const std::string& e) { + t.diag(e); } return 0; diff --git a/test/variant_divide.test.cpp b/test/variant_divide.test.cpp index 676c25870..a42c61664 100644 --- a/test/variant_divide.test.cpp +++ b/test/variant_divide.test.cpp @@ -27,175 +27,287 @@ #include // cmake.h include header must come first -#include -#include #include +#include + +#include #define EPSILON 0.0001 //////////////////////////////////////////////////////////////////////////////// -int main (int, char**) -{ - UnitTest t (44); +int main(int, char**) { + UnitTest t(44); - Variant v0 (true); - Variant v1 (42); - Variant v2 (3.14); - Variant v3 ("foo"); - Variant v4 (1234567890, Variant::type_date); - Variant v5 (1200, Variant::type_duration); + Variant v0(true); + Variant v1(42); + Variant v2(3.14); + Variant v3("foo"); + Variant v4(1234567890, Variant::type_date); + Variant v5(1200, Variant::type_duration); // boolean / boolean -> ERROR - try {Variant v00 = v0 / v0; t.fail ("true / true --> error");} - catch (...) {t.pass ("true / true --> error");} + try { + Variant v00 = v0 / v0; + t.fail("true / true --> error"); + } catch (...) { + t.pass("true / true --> error"); + } // boolean / integer -> ERROR - try {Variant v01 = v0 / v1; t.fail ("true / 42 --> error");} - catch (...) {t.pass ("true / 42 --> error");} + try { + Variant v01 = v0 / v1; + t.fail("true / 42 --> error"); + } catch (...) { + t.pass("true / 42 --> error"); + } // boolean / real -> ERROR - try {Variant v02 = v0 / v2; t.fail ("true / 3.14 --> error");} - catch (...) {t.pass ("true / 3.14 --> error");} + try { + Variant v02 = v0 / v2; + t.fail("true / 3.14 --> error"); + } catch (...) { + t.pass("true / 3.14 --> error"); + } // boolean / string -> ERROR - try {Variant v03 = v0 / v3; t.fail ("true / foo --> error");} - catch (...) {t.pass ("true / foo --> error");} + try { + Variant v03 = v0 / v3; + t.fail("true / foo --> error"); + } catch (...) { + t.pass("true / foo --> error"); + } // boolean / date -> ERROR - try {Variant v04 = v0 / v4; t.fail ("true / 1234567890 --> error");} - catch (...) {t.pass ("true / 1234567890 --> error");} + try { + Variant v04 = v0 / v4; + t.fail("true / 1234567890 --> error"); + } catch (...) { + t.pass("true / 1234567890 --> error"); + } // boolean / duration -> ERROR - try {Variant v05 = v0 / v5; t.fail ("true / 1200 --> error");} - catch (...) {t.pass ("true / 1200 --> error");} + try { + Variant v05 = v0 / v5; + t.fail("true / 1200 --> error"); + } catch (...) { + t.pass("true / 1200 --> error"); + } // integer / boolean -> ERROR - try {Variant v10 = v1 / v0; t.fail ("42 / true --> error");} - catch (...) {t.pass ("42 / true --> error");} + try { + Variant v10 = v1 / v0; + t.fail("42 / true --> error"); + } catch (...) { + t.pass("42 / true --> error"); + } // integer / integer -> integer Variant v11 = v1 / v1; - t.is (v11.type (), Variant::type_integer, "42 / 42 --> integer"); - t.is (v11.get_integer (), 1, "42 / 42 --> 1"); + t.is(v11.type(), Variant::type_integer, "42 / 42 --> integer"); + t.is(v11.get_integer(), 1, "42 / 42 --> 1"); // integer / real -> real Variant v12 = v1 / v2; - t.is (v12.type (), Variant::type_real, "42 / 3.14 --> real"); - t.is (v12.get_real (), 13.3757, EPSILON, "42 / 3.14 --> 13.3757"); + t.is(v12.type(), Variant::type_real, "42 / 3.14 --> real"); + t.is(v12.get_real(), 13.3757, EPSILON, "42 / 3.14 --> 13.3757"); // integer / string -> ERROR - try {Variant v13 = v1 / v3; t.fail ("42 / foo --> error");} - catch (...) {t.pass ("42 / foo --> error");} + try { + Variant v13 = v1 / v3; + t.fail("42 / foo --> error"); + } catch (...) { + t.pass("42 / foo --> error"); + } // integer / date -> ERROR - try {Variant v14 = v1 / v4; t.fail ("42 / 1234567890 --> error");} - catch (...) {t.pass ("42 / 1234567890 --> error");} + try { + Variant v14 = v1 / v4; + t.fail("42 / 1234567890 --> error"); + } catch (...) { + t.pass("42 / 1234567890 --> error"); + } // integer / duration -> duration Variant v15 = v1 / v5; - t.is (v15.type (), Variant::type_duration, "42 / 1200 --> duration"); - t.is (v15.get_duration (), 0, "42 / 1200 --> 0"); + t.is(v15.type(), Variant::type_duration, "42 / 1200 --> duration"); + t.is(v15.get_duration(), 0, "42 / 1200 --> 0"); // real / boolean -> ERROR - try {Variant v20 = v2 / v0; t.fail ("3.14 / true --> error");} - catch (...) {t.pass ("3.14 / true --> error");} + try { + Variant v20 = v2 / v0; + t.fail("3.14 / true --> error"); + } catch (...) { + t.pass("3.14 / true --> error"); + } // real / integer -> real Variant v21 = v2 / v1; - t.is (v21.type (), Variant::type_real, "3.14 / 42 --> real"); - t.is (v21.get_real (), 0.0747, EPSILON, "3.14 / 42 --> 0.0747"); + t.is(v21.type(), Variant::type_real, "3.14 / 42 --> real"); + t.is(v21.get_real(), 0.0747, EPSILON, "3.14 / 42 --> 0.0747"); // real / real -> real Variant v22 = v2 / v2; - t.is (v22.type (), Variant::type_real, "3.14 / 3.14 --> real"); - t.is (v22.get_real (), 1.0, EPSILON, "3.14 / 3.14 --> 1.0"); + t.is(v22.type(), Variant::type_real, "3.14 / 3.14 --> real"); + t.is(v22.get_real(), 1.0, EPSILON, "3.14 / 3.14 --> 1.0"); // real / string -> error - try {Variant v23 = v2 / v3; t.fail ("3.14 / foo --> error");} - catch (...) {t.pass ("3.14 / foo --> error");} + try { + Variant v23 = v2 / v3; + t.fail("3.14 / foo --> error"); + } catch (...) { + t.pass("3.14 / foo --> error"); + } // real / date -> error - try {Variant v24 = v2 / v4; t.fail ("3.14 / 1234567890 --> error");} - catch (...) {t.pass ("3.14 / 1234567890 --> error");} + try { + Variant v24 = v2 / v4; + t.fail("3.14 / 1234567890 --> error"); + } catch (...) { + t.pass("3.14 / 1234567890 --> error"); + } // real / duration -> duration Variant v25 = v2 / v5; - t.is (v25.type (), Variant::type_duration, "3.14 / 1200 --> duration"); - t.is (v25.get_duration (), 0, "3.14 / 1200 --> 0"); + t.is(v25.type(), Variant::type_duration, "3.14 / 1200 --> duration"); + t.is(v25.get_duration(), 0, "3.14 / 1200 --> 0"); // string / boolean -> ERROR - try {Variant v30 = v3 / v0; t.fail ("foo / true --> error");} - catch (...) {t.pass ("foo / true --> error");} + try { + Variant v30 = v3 / v0; + t.fail("foo / true --> error"); + } catch (...) { + t.pass("foo / true --> error"); + } // string / integer -> ERROR - try {Variant v31 = v3 / v1; t.fail ("foo / 42 --> error");} - catch (...) {t.pass ("foo / 42 --> error");} + try { + Variant v31 = v3 / v1; + t.fail("foo / 42 --> error"); + } catch (...) { + t.pass("foo / 42 --> error"); + } // string / real -> ERROR - try {Variant v32 = v3 / v2; t.fail ("foo / 3.14 --> error");} - catch (...) {t.pass ("foo / 3.14 --> error");} + try { + Variant v32 = v3 / v2; + t.fail("foo / 3.14 --> error"); + } catch (...) { + t.pass("foo / 3.14 --> error"); + } // string / string -> ERROR - try {Variant v33 = v3 / v3; t.fail ("foo / foo --> error");} - catch (...) {t.pass ("foo / foo --> error");} + try { + Variant v33 = v3 / v3; + t.fail("foo / foo --> error"); + } catch (...) { + t.pass("foo / foo --> error"); + } // string / date -> ERROR - try {Variant v34 = v3 / v4; t.fail ("foo / 1234567890 --> error");} - catch (...) {t.pass ("foo / 1234567890 --> error");} + try { + Variant v34 = v3 / v4; + t.fail("foo / 1234567890 --> error"); + } catch (...) { + t.pass("foo / 1234567890 --> error"); + } // string / duration -> ERROR - try {Variant v35 = v3 / v5; t.fail ("foo / 1200 --> error");} - catch (...) {t.pass ("foo / 1200 --> error");} + try { + Variant v35 = v3 / v5; + t.fail("foo / 1200 --> error"); + } catch (...) { + t.pass("foo / 1200 --> error"); + } // date / boolean -> ERROR - try {Variant v40 = v4 / v0; t.fail ("1234567890 / true --> error");} - catch (...) {t.pass ("1234567890 / true --> error");} + try { + Variant v40 = v4 / v0; + t.fail("1234567890 / true --> error"); + } catch (...) { + t.pass("1234567890 / true --> error"); + } // date / integer -> ERROR - try {Variant v41 = v4 / v1; t.fail ("1234567890 / 42 --> error");} - catch (...) {t.pass ("1234567890 / 42 --> error");} + try { + Variant v41 = v4 / v1; + t.fail("1234567890 / 42 --> error"); + } catch (...) { + t.pass("1234567890 / 42 --> error"); + } // date / real -> ERROR - try {Variant v42 = v4 / v2; t.fail ("1234567890 / 3.14 --> error");} - catch (...) {t.pass ("1234567890 / 3.14 --> error");} + try { + Variant v42 = v4 / v2; + t.fail("1234567890 / 3.14 --> error"); + } catch (...) { + t.pass("1234567890 / 3.14 --> error"); + } // date / string -> ERROR - try {Variant v43 = v4 / v3; t.fail ("1234567890 / foo --> error");} - catch (...) {t.pass ("1234567890 / foo --> error");} + try { + Variant v43 = v4 / v3; + t.fail("1234567890 / foo --> error"); + } catch (...) { + t.pass("1234567890 / foo --> error"); + } // date / date -> ERROR - try {Variant v44 = v4 / v4; t.fail ("1234567890 / 1234567890 --> error");} - catch (...) {t.pass ("1234567890 / 1234567890 --> error");} + try { + Variant v44 = v4 / v4; + t.fail("1234567890 / 1234567890 --> error"); + } catch (...) { + t.pass("1234567890 / 1234567890 --> error"); + } // date / duration -> ERROR - try {Variant v45 = v4 / v5; t.fail ("1234567890 / 1200 --> error");} - catch (...) {t.pass ("1234567890 / 1200 --> error");} + try { + Variant v45 = v4 / v5; + t.fail("1234567890 / 1200 --> error"); + } catch (...) { + t.pass("1234567890 / 1200 --> error"); + } // duration / boolean -> ERROR - try {Variant v50 = v5 / v0; t.fail ("1200 / true --> error");} - catch (...) {t.pass ("1200 / true --> error");} + try { + Variant v50 = v5 / v0; + t.fail("1200 / true --> error"); + } catch (...) { + t.pass("1200 / true --> error"); + } // duration / integer -> duration Variant v51 = v5 / v1; - t.is (v51.type (), Variant::type_duration, "1200 / 42 --> duration"); - t.is (v51.get_duration (), 28, "1200 / 42 --> 28"); + t.is(v51.type(), Variant::type_duration, "1200 / 42 --> duration"); + t.is(v51.get_duration(), 28, "1200 / 42 --> 28"); // duration / real -> duration Variant v52 = v5 / v2; - t.is (v52.type (), Variant::type_duration, "1200 / 3.14 --> duration"); - t.is (v52.get_duration (), 382, "1200 / 3.14 --> 382"); + t.is(v52.type(), Variant::type_duration, "1200 / 3.14 --> duration"); + t.is(v52.get_duration(), 382, "1200 / 3.14 --> 382"); // duration / string -> string - try {Variant v53 = v5 / v3; t.fail ("1200 / foo --> error");} - catch (...) {t.pass ("1200 / foo --> error");} + try { + Variant v53 = v5 / v3; + t.fail("1200 / foo --> error"); + } catch (...) { + t.pass("1200 / foo --> error"); + } // duration / date -> date - try {Variant v54 = v5 / v4; t.fail ("1200 / 1234567890 --> error");} - catch (...) {t.pass ("1200 / 1234567890 --> error");} + try { + Variant v54 = v5 / v4; + t.fail("1200 / 1234567890 --> error"); + } catch (...) { + t.pass("1200 / 1234567890 --> error"); + } // duration / duration -> duration - try {Variant v55 = v5 / v5; t.fail ("1200 / 1200 --> error");} - catch (...) {t.pass ("1200 / 1200 --> error");} + try { + Variant v55 = v5 / v5; + t.fail("1200 / 1200 --> error"); + } catch (...) { + t.pass("1200 / 1200 --> error"); + } return 0; } diff --git a/test/variant_equal.test.cpp b/test/variant_equal.test.cpp index 5b8c6c530..f09f9a28d 100644 --- a/test/variant_equal.test.cpp +++ b/test/variant_equal.test.cpp @@ -27,165 +27,165 @@ #include // cmake.h include header must come first -#include -#include #include +#include + +#include //////////////////////////////////////////////////////////////////////////////// -int main (int, char**) -{ - UnitTest t (72); +int main(int, char**) { + UnitTest t(72); - Variant v0 (true); - Variant v1 (42); - Variant v2 (3.14); - Variant v3 ("foo"); - Variant v4 (1234567890, Variant::type_date); - Variant v5 (1200, Variant::type_duration); + Variant v0(true); + Variant v1(42); + Variant v2(3.14); + Variant v3("foo"); + Variant v4(1234567890, Variant::type_date); + Variant v5(1200, Variant::type_duration); Variant v00 = v0 == v0; - t.is (v00.type (), Variant::type_boolean, "true == true --> boolean"); - t.is (v00.get_bool (), true, "true == true --> true"); + t.is(v00.type(), Variant::type_boolean, "true == true --> boolean"); + t.is(v00.get_bool(), true, "true == true --> true"); Variant v01 = v0 == v1; - t.is (v01.type (), Variant::type_boolean, "true == 42 --> boolean"); - t.is (v01.get_bool (), false, "true == 42 --> false"); + t.is(v01.type(), Variant::type_boolean, "true == 42 --> boolean"); + t.is(v01.get_bool(), false, "true == 42 --> false"); Variant v02 = v0 == v2; - t.is (v02.type (), Variant::type_boolean, "true == 3.14 --> boolean"); - t.is (v02.get_bool (), false, "true == 3.14 --> false"); + t.is(v02.type(), Variant::type_boolean, "true == 3.14 --> boolean"); + t.is(v02.get_bool(), false, "true == 3.14 --> false"); Variant v03 = v0 == v3; - t.is (v03.type (), Variant::type_boolean, "true == 'foo' --> boolean"); - t.is (v03.get_bool (), false, "true == 'foo' --> false"); + t.is(v03.type(), Variant::type_boolean, "true == 'foo' --> boolean"); + t.is(v03.get_bool(), false, "true == 'foo' --> false"); Variant v04 = v0 == v4; - t.is (v04.type (), Variant::type_boolean, "true == 1234567890 --> boolean"); - t.is (v04.get_bool (), false, "true == 1234567890 --> false"); + t.is(v04.type(), Variant::type_boolean, "true == 1234567890 --> boolean"); + t.is(v04.get_bool(), false, "true == 1234567890 --> false"); Variant v05 = v0 == v5; - t.is (v05.type (), Variant::type_boolean, "true == 1200 --> boolean"); - t.is (v05.get_bool (), false, "true == 1200 --> false"); + t.is(v05.type(), Variant::type_boolean, "true == 1200 --> boolean"); + t.is(v05.get_bool(), false, "true == 1200 --> false"); Variant v10 = v1 == v0; - t.is (v10.type (), Variant::type_boolean, "42 == true --> boolean"); - t.is (v10.get_bool (), false, "42 == true --> false"); + t.is(v10.type(), Variant::type_boolean, "42 == true --> boolean"); + t.is(v10.get_bool(), false, "42 == true --> false"); Variant v11 = v1 == v1; - t.is (v11.type (), Variant::type_boolean, "42 == 42 --> boolean"); - t.is (v11.get_bool (), true, "42 == 42 --> true"); + t.is(v11.type(), Variant::type_boolean, "42 == 42 --> boolean"); + t.is(v11.get_bool(), true, "42 == 42 --> true"); Variant v12 = v1 == v2; - t.is (v12.type (), Variant::type_boolean, "42 == 3.14 --> boolean"); - t.is (v12.get_bool (), false, "42 == 3.14 --> false"); + t.is(v12.type(), Variant::type_boolean, "42 == 3.14 --> boolean"); + t.is(v12.get_bool(), false, "42 == 3.14 --> false"); Variant v13 = v1 == v3; - t.is (v13.type (), Variant::type_boolean, "42 == 'foo' --> boolean"); - t.is (v13.get_bool (), false, "42 == 'foo' --> false"); + t.is(v13.type(), Variant::type_boolean, "42 == 'foo' --> boolean"); + t.is(v13.get_bool(), false, "42 == 'foo' --> false"); Variant v14 = v1 == v4; - t.is (v04.type (), Variant::type_boolean, "42 == 1234567890 --> boolean"); - t.is (v04.get_bool (), false, "42 == 1234567890 --> false"); + t.is(v04.type(), Variant::type_boolean, "42 == 1234567890 --> boolean"); + t.is(v04.get_bool(), false, "42 == 1234567890 --> false"); Variant v15 = v1 == v5; - t.is (v15.type (), Variant::type_boolean, "42 == 1200 --> boolean"); - t.is (v15.get_bool (), false, "42 == 1200 --> false"); + t.is(v15.type(), Variant::type_boolean, "42 == 1200 --> boolean"); + t.is(v15.get_bool(), false, "42 == 1200 --> false"); Variant v20 = v2 == v0; - t.is (v20.type (), Variant::type_boolean, "3.14 == true --> boolean"); - t.is (v20.get_bool (), false, "3.14 == true --> false"); + t.is(v20.type(), Variant::type_boolean, "3.14 == true --> boolean"); + t.is(v20.get_bool(), false, "3.14 == true --> false"); Variant v21 = v2 == v1; - t.is (v21.type (), Variant::type_boolean, "3.14 == 42 --> boolean"); - t.is (v21.get_bool (), false, "3.14 == 42 --> false"); + t.is(v21.type(), Variant::type_boolean, "3.14 == 42 --> boolean"); + t.is(v21.get_bool(), false, "3.14 == 42 --> false"); Variant v22 = v2 == v2; - t.is (v22.type (), Variant::type_boolean, "3.14 == 3.14 --> boolean"); - t.is (v22.get_bool (), true, "3.14 == 3.14 --> true"); + t.is(v22.type(), Variant::type_boolean, "3.14 == 3.14 --> boolean"); + t.is(v22.get_bool(), true, "3.14 == 3.14 --> true"); Variant v23 = v2 == v3; - t.is (v23.type (), Variant::type_boolean, "3.14 == 'foo' --> boolean"); - t.is (v23.get_bool (), false, "3.14 == 'foo' --> false"); + t.is(v23.type(), Variant::type_boolean, "3.14 == 'foo' --> boolean"); + t.is(v23.get_bool(), false, "3.14 == 'foo' --> false"); Variant v24 = v2 == v4; - t.is (v24.type (), Variant::type_boolean, "3.14 == 1234567890 --> boolean"); - t.is (v24.get_bool (), false, "3.14 == 1234567890 --> false"); + t.is(v24.type(), Variant::type_boolean, "3.14 == 1234567890 --> boolean"); + t.is(v24.get_bool(), false, "3.14 == 1234567890 --> false"); Variant v25 = v2 == v5; - t.is (v25.type (), Variant::type_boolean, "3.14 == 1200 --> boolean"); - t.is (v25.get_bool (), false, "3.14 == 1200 --> false"); + t.is(v25.type(), Variant::type_boolean, "3.14 == 1200 --> boolean"); + t.is(v25.get_bool(), false, "3.14 == 1200 --> false"); Variant v30 = v3 == v0; - t.is (v30.type (), Variant::type_boolean, "'foo' == true --> boolean"); - t.is (v30.get_bool (), false, "'foo' == true --> false"); + t.is(v30.type(), Variant::type_boolean, "'foo' == true --> boolean"); + t.is(v30.get_bool(), false, "'foo' == true --> false"); Variant v31 = v3 == v1; - t.is (v31.type (), Variant::type_boolean, "'foo' == 42 --> boolean"); - t.is (v31.get_bool (), false, "'foo' == 42 --> false"); + t.is(v31.type(), Variant::type_boolean, "'foo' == 42 --> boolean"); + t.is(v31.get_bool(), false, "'foo' == 42 --> false"); Variant v32 = v3 == v2; - t.is (v32.type (), Variant::type_boolean, "'foo' == 3.14 --> boolean"); - t.is (v32.get_bool (), false, "'foo' == 3.14 --> false"); + t.is(v32.type(), Variant::type_boolean, "'foo' == 3.14 --> boolean"); + t.is(v32.get_bool(), false, "'foo' == 3.14 --> false"); Variant v33 = v3 == v3; - t.is (v33.type (), Variant::type_boolean, "'foo' == 'foo' --> boolean"); - t.is (v33.get_bool (), true, "'foo' == 'foo' --> true"); + t.is(v33.type(), Variant::type_boolean, "'foo' == 'foo' --> boolean"); + t.is(v33.get_bool(), true, "'foo' == 'foo' --> true"); Variant v34 = v3 == v4; - t.is (v34.type (), Variant::type_boolean, "'foo' == 1234567890 --> boolean"); - t.is (v34.get_bool (), false, "'foo' == 1234567890 --> false"); + t.is(v34.type(), Variant::type_boolean, "'foo' == 1234567890 --> boolean"); + t.is(v34.get_bool(), false, "'foo' == 1234567890 --> false"); Variant v35 = v3 == v5; - t.is (v35.type (), Variant::type_boolean, "'foo' == 1200 --> boolean"); - t.is (v35.get_bool (), false, "'foo' == 1200 --> false"); + t.is(v35.type(), Variant::type_boolean, "'foo' == 1200 --> boolean"); + t.is(v35.get_bool(), false, "'foo' == 1200 --> false"); Variant v40 = v4 == v0; - t.is (v40.type (), Variant::type_boolean, "1234567890 == true --> boolean"); - t.is (v40.get_bool (), false, "1234567890 == true --> false"); + t.is(v40.type(), Variant::type_boolean, "1234567890 == true --> boolean"); + t.is(v40.get_bool(), false, "1234567890 == true --> false"); Variant v41 = v4 == v1; - t.is (v41.type (), Variant::type_boolean, "1234567890 == 42 --> boolean"); - t.is (v41.get_bool (), false, "1234567890 == 42 --> false"); + t.is(v41.type(), Variant::type_boolean, "1234567890 == 42 --> boolean"); + t.is(v41.get_bool(), false, "1234567890 == 42 --> false"); Variant v42 = v4 == v2; - t.is (v42.type (), Variant::type_boolean, "1234567890 == 3.14 --> boolean"); - t.is (v42.get_bool (), false, "1234567890 == 3.14 --> false"); + t.is(v42.type(), Variant::type_boolean, "1234567890 == 3.14 --> boolean"); + t.is(v42.get_bool(), false, "1234567890 == 3.14 --> false"); Variant v43 = v4 == v3; - t.is (v43.type (), Variant::type_boolean, "1234567890 == 'foo' --> boolean"); - t.is (v43.get_bool (), false, "1234567890 == 'foo' --> false"); + t.is(v43.type(), Variant::type_boolean, "1234567890 == 'foo' --> boolean"); + t.is(v43.get_bool(), false, "1234567890 == 'foo' --> false"); Variant v44 = v4 == v4; - t.is (v44.type (), Variant::type_boolean, "1234567890 == 1234567890 --> boolean"); - t.is (v44.get_bool (), true, "1234567890 == 1234567890 --> true"); + t.is(v44.type(), Variant::type_boolean, "1234567890 == 1234567890 --> boolean"); + t.is(v44.get_bool(), true, "1234567890 == 1234567890 --> true"); Variant v45 = v4 == v5; - t.is (v45.type (), Variant::type_boolean, "1234567890 == 1200 --> boolean"); - t.is (v45.get_bool (), false, "1234567890 == 1200 --> false"); + t.is(v45.type(), Variant::type_boolean, "1234567890 == 1200 --> boolean"); + t.is(v45.get_bool(), false, "1234567890 == 1200 --> false"); Variant v50 = v5 == v0; - t.is (v50.type (), Variant::type_boolean, "1200 == true --> boolean"); - t.is (v50.get_bool (), false, "1200 == true --> false"); + t.is(v50.type(), Variant::type_boolean, "1200 == true --> boolean"); + t.is(v50.get_bool(), false, "1200 == true --> false"); Variant v51 = v5 == v1; - t.is (v51.type (), Variant::type_boolean, "1200 == 42 --> boolean"); - t.is (v51.get_bool (), false, "1200 == 42 --> false"); + t.is(v51.type(), Variant::type_boolean, "1200 == 42 --> boolean"); + t.is(v51.get_bool(), false, "1200 == 42 --> false"); Variant v52 = v5 == v2; - t.is (v52.type (), Variant::type_boolean, "1200 == 3.14 --> boolean"); - t.is (v52.get_bool (), false, "1200 == 3.14 --> false"); + t.is(v52.type(), Variant::type_boolean, "1200 == 3.14 --> boolean"); + t.is(v52.get_bool(), false, "1200 == 3.14 --> false"); Variant v53 = v5 == v3; - t.is (v53.type (), Variant::type_boolean, "1200 == 'foo' --> boolean"); - t.is (v53.get_bool (), false, "1200 == 'foo' --> false"); + t.is(v53.type(), Variant::type_boolean, "1200 == 'foo' --> boolean"); + t.is(v53.get_bool(), false, "1200 == 'foo' --> false"); Variant v54 = v5 == v4; - t.is (v04.type (), Variant::type_boolean, "1200 == 1234567890 --> boolean"); - t.is (v04.get_bool (), false, "1200 == 1234567890 --> false"); + t.is(v04.type(), Variant::type_boolean, "1200 == 1234567890 --> boolean"); + t.is(v04.get_bool(), false, "1200 == 1234567890 --> false"); Variant v55 = v5 == v5; - t.is (v55.type (), Variant::type_boolean, "1200 == 1200 --> boolean"); - t.is (v55.get_bool (), true, "1200 == 1200 --> true"); + t.is(v55.type(), Variant::type_boolean, "1200 == 1200 --> boolean"); + t.is(v55.get_bool(), true, "1200 == 1200 --> true"); return 0; } diff --git a/test/variant_exp.test.cpp b/test/variant_exp.test.cpp index ac7c1e085..20fec4fd2 100644 --- a/test/variant_exp.test.cpp +++ b/test/variant_exp.test.cpp @@ -27,167 +27,303 @@ #include // cmake.h include header must come first -#include -#include #include +#include + +#include //////////////////////////////////////////////////////////////////////////////// -int main (int, char**) -{ - UnitTest t (38); +int main(int, char**) { + UnitTest t(38); - Variant v0 (true); - Variant v1 (42); - Variant v2 (3.14); - Variant v3 ("foo"); - Variant v4 (1234567890, Variant::type_date); - Variant v5 (1200, Variant::type_duration); + Variant v0(true); + Variant v1(42); + Variant v2(3.14); + Variant v3("foo"); + Variant v4(1234567890, Variant::type_date); + Variant v5(1200, Variant::type_duration); // boolean ^ boolean -> ERROR - try {Variant v00 = v0 ^ v0; t.fail ("true ^ true --> error");} - catch (...) {t.pass ("true ^ true --> error");} + try { + Variant v00 = v0 ^ v0; + t.fail("true ^ true --> error"); + } catch (...) { + t.pass("true ^ true --> error"); + } // boolean ^ integer -> ERROR - try {Variant v01 = v0 ^ v1; t.fail ("true ^ 42 --> error");} - catch (...) {t.pass ("true ^ 42 --> error");} + try { + Variant v01 = v0 ^ v1; + t.fail("true ^ 42 --> error"); + } catch (...) { + t.pass("true ^ 42 --> error"); + } // boolean ^ real -> ERROR - try {Variant v02 = v0 ^ v2; t.fail ("true ^ 3.14 --> error");} - catch (...) {t.pass ("true ^ 3.14 --> error");} + try { + Variant v02 = v0 ^ v2; + t.fail("true ^ 3.14 --> error"); + } catch (...) { + t.pass("true ^ 3.14 --> error"); + } // boolean ^ string -> ERROR - try {Variant v03 = v0 ^ v3; t.fail ("true ^ foo --> error");} - catch (...) {t.pass ("true ^ foo --> error");} + try { + Variant v03 = v0 ^ v3; + t.fail("true ^ foo --> error"); + } catch (...) { + t.pass("true ^ foo --> error"); + } // boolean ^ date -> ERROR - try {Variant v04 = v0 ^ v4; t.fail ("true ^ 1234567890 --> error");} - catch (...) {t.pass ("true ^ 1234567890 --> error");} + try { + Variant v04 = v0 ^ v4; + t.fail("true ^ 1234567890 --> error"); + } catch (...) { + t.pass("true ^ 1234567890 --> error"); + } // boolean ^ duration -> ERROR - try {Variant v05 = v0 ^ v5; t.fail ("true ^ 1200 --> error");} - catch (...) {t.pass ("true ^ 1200 --> error");} + try { + Variant v05 = v0 ^ v5; + t.fail("true ^ 1200 --> error"); + } catch (...) { + t.pass("true ^ 1200 --> error"); + } // integer ^ boolean -> ERROR - try {Variant v10 = v1 ^ v0; t.fail ("42 ^ true --> error");} - catch (...) {t.pass ("42 ^ true --> error");} + try { + Variant v10 = v1 ^ v0; + t.fail("42 ^ true --> error"); + } catch (...) { + t.pass("42 ^ true --> error"); + } // integer ^ integer -> integer - Variant v11 = v1 ^ Variant (2); - t.is (v11.type (), Variant::type_integer, "42 ^ 2 --> integer"); - t.is (v11.get_integer (), 1764, "42 ^ 2 --> 1764"); + Variant v11 = v1 ^ Variant(2); + t.is(v11.type(), Variant::type_integer, "42 ^ 2 --> integer"); + t.is(v11.get_integer(), 1764, "42 ^ 2 --> 1764"); // integer ^ real -> real - try {Variant v12 = v1 ^ v2; t.fail ("42 ^ 3.14 --> error");} - catch (...) {t.pass ("42 ^ 3.14 --> error");} + try { + Variant v12 = v1 ^ v2; + t.fail("42 ^ 3.14 --> error"); + } catch (...) { + t.pass("42 ^ 3.14 --> error"); + } // integer ^ string -> ERROR - try {Variant v13 = v1 ^ v3; t.fail ("42 ^ foo --> error");} - catch (...) {t.pass ("42 ^ foo --> error");} + try { + Variant v13 = v1 ^ v3; + t.fail("42 ^ foo --> error"); + } catch (...) { + t.pass("42 ^ foo --> error"); + } // integer ^ date -> ERROR - try {Variant v14 = v1 ^ v4; t.fail ("42 ^ 1234567890 --> error");} - catch (...) {t.pass ("42 ^ 1234567890 --> error");} + try { + Variant v14 = v1 ^ v4; + t.fail("42 ^ 1234567890 --> error"); + } catch (...) { + t.pass("42 ^ 1234567890 --> error"); + } // integer ^ duration -> ERROR - try {Variant v15 = v1 ^ v5; t.fail ("42 ^ 1200 --> error");} - catch (...) {t.pass ("42 ^ 1200 --> error");} + try { + Variant v15 = v1 ^ v5; + t.fail("42 ^ 1200 --> error"); + } catch (...) { + t.pass("42 ^ 1200 --> error"); + } // real ^ boolean -> ERROR - try {Variant v20 = v2 ^ v0; t.fail ("3.14 ^ true --> error");} - catch (...) {t.pass ("3.14 ^ true --> error");} + try { + Variant v20 = v2 ^ v0; + t.fail("3.14 ^ true --> error"); + } catch (...) { + t.pass("3.14 ^ true --> error"); + } // real ^ integer -> real - Variant v21 = v2 ^ Variant (2); - t.is (v21.type (), Variant::type_real, "3.14 ^ 2 --> real"); - t.is (v21.get_real (), 9.8596, 0.001, "3.14 ^ 2 --> 9.8596"); + Variant v21 = v2 ^ Variant(2); + t.is(v21.type(), Variant::type_real, "3.14 ^ 2 --> real"); + t.is(v21.get_real(), 9.8596, 0.001, "3.14 ^ 2 --> 9.8596"); // real ^ real -> ERROR - try {Variant v22 = v2 ^ v2; t.fail ("3.14 ^ 3.14 --> error");} - catch (...) {t.pass ("3.14 ^ 3.14 --> error");} + try { + Variant v22 = v2 ^ v2; + t.fail("3.14 ^ 3.14 --> error"); + } catch (...) { + t.pass("3.14 ^ 3.14 --> error"); + } // real ^ string -> ERROR - try {Variant v23 = v2 ^ v3; t.fail ("3.14 ^ foo --> error");} - catch (...) {t.pass ("3.14 ^ foo --> error");} + try { + Variant v23 = v2 ^ v3; + t.fail("3.14 ^ foo --> error"); + } catch (...) { + t.pass("3.14 ^ foo --> error"); + } // real ^ date -> ERROR - try {Variant v24 = v2 ^ v4; t.fail ("3.14 ^ 1234567890 --> error");} - catch (...) {t.pass ("3.14 ^ 1234567890 --> error");} + try { + Variant v24 = v2 ^ v4; + t.fail("3.14 ^ 1234567890 --> error"); + } catch (...) { + t.pass("3.14 ^ 1234567890 --> error"); + } // real ^ duration -> ERROR - try {Variant v25 = v2 ^ v5; t.fail ("3.14 ^ 1200 --> error");} - catch (...) {t.pass ("3.14 ^ 1200 --> error");} + try { + Variant v25 = v2 ^ v5; + t.fail("3.14 ^ 1200 --> error"); + } catch (...) { + t.pass("3.14 ^ 1200 --> error"); + } // string ^ boolean -> ERROR - try {Variant v30 = v3 ^ v0; t.fail ("foo ^ true --> error");} - catch (...) {t.pass ("foo ^ true --> error");} + try { + Variant v30 = v3 ^ v0; + t.fail("foo ^ true --> error"); + } catch (...) { + t.pass("foo ^ true --> error"); + } // string ^ integer -> ERROR - try {Variant v31 = v3 ^ v1; t.fail ("foo ^ 42 --> error");} - catch (...) {t.pass ("foo ^ 42 --> error");} + try { + Variant v31 = v3 ^ v1; + t.fail("foo ^ 42 --> error"); + } catch (...) { + t.pass("foo ^ 42 --> error"); + } // string ^ real -> ERROR - try {Variant v32 = v3 ^ v2; t.fail ("foo ^ 3.14 --> error");} - catch (...) {t.pass ("foo ^ 3.14 --> error");} + try { + Variant v32 = v3 ^ v2; + t.fail("foo ^ 3.14 --> error"); + } catch (...) { + t.pass("foo ^ 3.14 --> error"); + } // string ^ string -> ERROR - try {Variant v33 = v3 ^ v3; t.fail ("foo ^ foo --> error");} - catch (...) {t.pass ("foo ^ foo --> error");} + try { + Variant v33 = v3 ^ v3; + t.fail("foo ^ foo --> error"); + } catch (...) { + t.pass("foo ^ foo --> error"); + } // string ^ date -> ERROR - try {Variant v34 = v3 ^ v4; t.fail ("foo ^ 1234567890 --> error");} - catch (...) {t.pass ("foo ^ 1234567890 --> error");} + try { + Variant v34 = v3 ^ v4; + t.fail("foo ^ 1234567890 --> error"); + } catch (...) { + t.pass("foo ^ 1234567890 --> error"); + } // string ^ duration -> ERROR - try {Variant v35 = v3 ^ v5; t.fail ("foo ^ 1200 --> error");} - catch (...) {t.pass ("foo ^ 1200 --> error");} + try { + Variant v35 = v3 ^ v5; + t.fail("foo ^ 1200 --> error"); + } catch (...) { + t.pass("foo ^ 1200 --> error"); + } // date ^ boolean -> ERROR - try {Variant v40 = v4 ^ v0; t.fail ("1234567890 ^ true --> error");} - catch (...) {t.pass ("1234567890 ^ true --> error");} + try { + Variant v40 = v4 ^ v0; + t.fail("1234567890 ^ true --> error"); + } catch (...) { + t.pass("1234567890 ^ true --> error"); + } // date ^ integer -> ERROR - try {Variant v41 = v4 ^ v1; t.fail ("1234567890 ^ 42 --> error");} - catch (...) {t.pass ("1234567890 ^ 42 --> error");} + try { + Variant v41 = v4 ^ v1; + t.fail("1234567890 ^ 42 --> error"); + } catch (...) { + t.pass("1234567890 ^ 42 --> error"); + } // date ^ real -> ERROR - try {Variant v42 = v4 ^ v2; t.fail ("1234567890 ^ 3.14 --> error");} - catch (...) {t.pass ("1234567890 ^ 3.14 --> error");} + try { + Variant v42 = v4 ^ v2; + t.fail("1234567890 ^ 3.14 --> error"); + } catch (...) { + t.pass("1234567890 ^ 3.14 --> error"); + } // date ^ string -> ERROR - try {Variant v43 = v4 ^ v3; t.fail ("1234567890 ^ foo --> error");} - catch (...) {t.pass ("1234567890 ^ foo --> error");} + try { + Variant v43 = v4 ^ v3; + t.fail("1234567890 ^ foo --> error"); + } catch (...) { + t.pass("1234567890 ^ foo --> error"); + } // date ^ date -> ERROR - try {Variant v44 = v4 ^ v4; t.fail ("1234567890 ^ 1234567890 --> error");} - catch (...) {t.pass ("1234567890 ^ 1234567890 --> error");} + try { + Variant v44 = v4 ^ v4; + t.fail("1234567890 ^ 1234567890 --> error"); + } catch (...) { + t.pass("1234567890 ^ 1234567890 --> error"); + } // date ^ duration -> ERROR - try {Variant v45 = v4 ^ v5; t.fail ("1234567890 ^ 1200 --> error");} - catch (...) {t.pass ("1234567890 ^ 1200 --> error");} + try { + Variant v45 = v4 ^ v5; + t.fail("1234567890 ^ 1200 --> error"); + } catch (...) { + t.pass("1234567890 ^ 1200 --> error"); + } // duration ^ boolean -> ERROR - try {Variant v50 = v5 ^ v0; t.fail ("1200 ^ true --> error");} - catch (...) {t.pass ("1200 ^ true --> error");} + try { + Variant v50 = v5 ^ v0; + t.fail("1200 ^ true --> error"); + } catch (...) { + t.pass("1200 ^ true --> error"); + } // duration ^ integer -> ERROR - try {Variant v51 = v5 ^ v1; t.fail ("1200 ^ 42 --> error");} - catch (...) {t.pass ("1200 ^ 42 --> error");} + try { + Variant v51 = v5 ^ v1; + t.fail("1200 ^ 42 --> error"); + } catch (...) { + t.pass("1200 ^ 42 --> error"); + } // duration ^ real -> ERROR - try {Variant v52 = v5 ^ v2; t.fail ("1200 ^ 3.14 --> error");} - catch (...) {t.pass ("1200 ^ 3.14 --> error");} + try { + Variant v52 = v5 ^ v2; + t.fail("1200 ^ 3.14 --> error"); + } catch (...) { + t.pass("1200 ^ 3.14 --> error"); + } // duration ^ string -> ERROR - try {Variant v53 = v5 ^ v3; t.fail ("1200 ^ foo --> error");} - catch (...) {t.pass ("1200 ^ foo --> error");} + try { + Variant v53 = v5 ^ v3; + t.fail("1200 ^ foo --> error"); + } catch (...) { + t.pass("1200 ^ foo --> error"); + } // duration ^ date -> ERROR - try {Variant v54 = v5 ^ v4; t.fail ("1200 ^ 1234567890 --> error");} - catch (...) {t.pass ("1200 ^ 1234567890 --> error");} + try { + Variant v54 = v5 ^ v4; + t.fail("1200 ^ 1234567890 --> error"); + } catch (...) { + t.pass("1200 ^ 1234567890 --> error"); + } // duration ^ duration -> ERROR - try {Variant v55 = v5 ^ v5; t.fail ("1200 ^ 1200 --> error");} - catch (...) {t.pass ("1200 ^ 1200 --> error");} + try { + Variant v55 = v5 ^ v5; + t.fail("1200 ^ 1200 --> error"); + } catch (...) { + t.pass("1200 ^ 1200 --> error"); + } return 0; } diff --git a/test/variant_gt.test.cpp b/test/variant_gt.test.cpp index 86d2b6317..a35f3cef4 100644 --- a/test/variant_gt.test.cpp +++ b/test/variant_gt.test.cpp @@ -27,168 +27,168 @@ #include // cmake.h include header must come first -#include -#include #include +#include + +#include //////////////////////////////////////////////////////////////////////////////// -int main (int, char**) -{ - UnitTest t (72); +int main(int, char**) { + UnitTest t(72); - Variant v0 (true); - Variant v1 (42); - Variant v2 (3.14); - Variant v3 ("foo"); - Variant v4 (1234567890, Variant::type_date); - Variant v5 (1200, Variant::type_duration); + Variant v0(true); + Variant v1(42); + Variant v2(3.14); + Variant v3("foo"); + Variant v4(1234567890, Variant::type_date); + Variant v5(1200, Variant::type_duration); Variant v00 = v0 > v0; - t.is (v00.type (), Variant::type_boolean, "true > true --> boolean"); - t.is (v00.get_bool (), false, "true > true --> false"); + t.is(v00.type(), Variant::type_boolean, "true > true --> boolean"); + t.is(v00.get_bool(), false, "true > true --> false"); Variant v01 = v0 > v1; - t.is (v01.type (), Variant::type_boolean, "true > 42 --> boolean"); - t.is (v01.get_bool (), false, "true > 42 --> false"); + t.is(v01.type(), Variant::type_boolean, "true > 42 --> boolean"); + t.is(v01.get_bool(), false, "true > 42 --> false"); Variant v02 = v0 > v2; - t.is (v02.type (), Variant::type_boolean, "true > 3.14 --> boolean"); - t.is (v02.get_bool (), false, "true > 3.14 --> false"); + t.is(v02.type(), Variant::type_boolean, "true > 3.14 --> boolean"); + t.is(v02.get_bool(), false, "true > 3.14 --> false"); Variant v03 = v0 > v3; - t.is (v03.type (), Variant::type_boolean, "true > 'foo' --> boolean"); - t.is (v03.get_bool (), true, "true > 'foo' --> true"); + t.is(v03.type(), Variant::type_boolean, "true > 'foo' --> boolean"); + t.is(v03.get_bool(), true, "true > 'foo' --> true"); Variant v04 = v0 > v4; - t.is (v04.type (), Variant::type_boolean, "true > 1234567890 --> boolean"); - t.is (v04.get_bool (), false, "true > 1234567890 --> false"); + t.is(v04.type(), Variant::type_boolean, "true > 1234567890 --> boolean"); + t.is(v04.get_bool(), false, "true > 1234567890 --> false"); Variant v05 = v0 > v5; - t.is (v05.type (), Variant::type_boolean, "true > 1200 --> boolean"); - t.is (v05.get_bool (), false, "true > 1200 --> false"); + t.is(v05.type(), Variant::type_boolean, "true > 1200 --> boolean"); + t.is(v05.get_bool(), false, "true > 1200 --> false"); Variant v10 = v1 > v0; - t.is (v10.type (), Variant::type_boolean, "42 > true --> boolean"); - t.is (v10.get_bool (), true, "42 > true --> true"); + t.is(v10.type(), Variant::type_boolean, "42 > true --> boolean"); + t.is(v10.get_bool(), true, "42 > true --> true"); Variant v11 = v1 > v1; - t.is (v11.type (), Variant::type_boolean, "42 > 42 --> boolean"); - t.is (v11.get_bool (), false, "42 > 42 --> false"); + t.is(v11.type(), Variant::type_boolean, "42 > 42 --> boolean"); + t.is(v11.get_bool(), false, "42 > 42 --> false"); Variant v12 = v1 > v2; - t.is (v12.type (), Variant::type_boolean, "42 > 3.14 --> boolean"); - t.is (v12.get_bool (), true, "42 > 3.14 --> true"); + t.is(v12.type(), Variant::type_boolean, "42 > 3.14 --> boolean"); + t.is(v12.get_bool(), true, "42 > 3.14 --> true"); Variant v13 = v1 > v3; - t.is (v13.type (), Variant::type_boolean, "42 > 'foo' --> boolean"); - t.is (v13.get_bool (), false, "42 > 'foo' --> false"); + t.is(v13.type(), Variant::type_boolean, "42 > 'foo' --> boolean"); + t.is(v13.get_bool(), false, "42 > 'foo' --> false"); Variant v14 = v1 > v4; - t.is (v04.type (), Variant::type_boolean, "42 > 1234567890 --> boolean"); - t.is (v04.get_bool (), false, "42 > 1234567890 --> false"); + t.is(v04.type(), Variant::type_boolean, "42 > 1234567890 --> boolean"); + t.is(v04.get_bool(), false, "42 > 1234567890 --> false"); Variant v15 = v1 > v5; - t.is (v15.type (), Variant::type_boolean, "42 > 1200 --> boolean"); - t.is (v15.get_bool (), false, "42 > 1200 --> false"); + t.is(v15.type(), Variant::type_boolean, "42 > 1200 --> boolean"); + t.is(v15.get_bool(), false, "42 > 1200 --> false"); Variant v20 = v2 > v0; - t.is (v20.type (), Variant::type_boolean, "3.14 > true --> boolean"); - t.is (v20.get_bool (), true, "3.14 > true --> true"); + t.is(v20.type(), Variant::type_boolean, "3.14 > true --> boolean"); + t.is(v20.get_bool(), true, "3.14 > true --> true"); Variant v21 = v2 > v1; - t.is (v21.type (), Variant::type_boolean, "3.14 > 42 --> boolean"); - t.is (v21.get_bool (), false, "3.14 > 42 --> false"); + t.is(v21.type(), Variant::type_boolean, "3.14 > 42 --> boolean"); + t.is(v21.get_bool(), false, "3.14 > 42 --> false"); Variant v22 = v2 > v2; - t.is (v22.type (), Variant::type_boolean, "3.14 > 3.14 --> boolean"); - t.is (v22.get_bool (), false, "3.14 > 3.14 --> false"); + t.is(v22.type(), Variant::type_boolean, "3.14 > 3.14 --> boolean"); + t.is(v22.get_bool(), false, "3.14 > 3.14 --> false"); Variant v23 = v2 > v3; - t.is (v23.type (), Variant::type_boolean, "3.14 > 'foo' --> boolean"); - t.is (v23.get_bool (), false, "3.14 > 'foo' --> false"); + t.is(v23.type(), Variant::type_boolean, "3.14 > 'foo' --> boolean"); + t.is(v23.get_bool(), false, "3.14 > 'foo' --> false"); Variant v24 = v2 > v4; - t.is (v24.type (), Variant::type_boolean, "3.14 > 1234567890 --> boolean"); - t.is (v24.get_bool (), false, "3.14 > 1234567890 --> false"); + t.is(v24.type(), Variant::type_boolean, "3.14 > 1234567890 --> boolean"); + t.is(v24.get_bool(), false, "3.14 > 1234567890 --> false"); Variant v25 = v2 > v5; - t.is (v25.type (), Variant::type_boolean, "3.14 > 1200 --> boolean"); - t.is (v25.get_bool (), false, "3.14 > 1200 --> false"); + t.is(v25.type(), Variant::type_boolean, "3.14 > 1200 --> boolean"); + t.is(v25.get_bool(), false, "3.14 > 1200 --> false"); Variant v30 = v3 > v0; - t.is (v30.type (), Variant::type_boolean, "'foo' > true --> boolean"); - t.is (v30.get_bool (), false, "'foo' > true --> false"); + t.is(v30.type(), Variant::type_boolean, "'foo' > true --> boolean"); + t.is(v30.get_bool(), false, "'foo' > true --> false"); Variant v31 = v3 > v1; - t.is (v31.type (), Variant::type_boolean, "'foo' > 42 --> boolean"); - t.is (v31.get_bool (), true, "'foo' > 42 --> true"); + t.is(v31.type(), Variant::type_boolean, "'foo' > 42 --> boolean"); + t.is(v31.get_bool(), true, "'foo' > 42 --> true"); Variant v32 = v3 > v2; - t.is (v32.type (), Variant::type_boolean, "'foo' > 3.14 --> boolean"); - t.is (v32.get_bool (), true, "'foo' > 3.14 --> true"); + t.is(v32.type(), Variant::type_boolean, "'foo' > 3.14 --> boolean"); + t.is(v32.get_bool(), true, "'foo' > 3.14 --> true"); Variant v33 = v3 > v3; - t.is (v33.type (), Variant::type_boolean, "'foo' > 'foo' --> boolean"); - t.is (v33.get_bool (), false, "'foo' > 'foo' --> false"); + t.is(v33.type(), Variant::type_boolean, "'foo' > 'foo' --> boolean"); + t.is(v33.get_bool(), false, "'foo' > 'foo' --> false"); Variant v34 = v3 > v4; - t.is (v34.type (), Variant::type_boolean, "'foo' > 1234567890 --> boolean"); - t.is (v34.get_bool (), false, "'foo' > 1234567890 --> false"); + t.is(v34.type(), Variant::type_boolean, "'foo' > 1234567890 --> boolean"); + t.is(v34.get_bool(), false, "'foo' > 1234567890 --> false"); Variant v35 = v3 > v5; - t.is (v35.type (), Variant::type_boolean, "'foo' > 1200 --> boolean"); - t.is (v35.get_bool (), false, "'foo' > 1200 --> false"); + t.is(v35.type(), Variant::type_boolean, "'foo' > 1200 --> boolean"); + t.is(v35.get_bool(), false, "'foo' > 1200 --> false"); Variant v40 = v4 > v0; - t.is (v40.type (), Variant::type_boolean, "1234567890 > true --> boolean"); - t.is (v40.get_bool (), true, "1234567890 > true --> true"); + t.is(v40.type(), Variant::type_boolean, "1234567890 > true --> boolean"); + t.is(v40.get_bool(), true, "1234567890 > true --> true"); Variant v41 = v4 > v1; - t.is (v41.type (), Variant::type_boolean, "1234567890 > 42 --> boolean"); - t.is (v41.get_bool (), true, "1234567890 > 42 --> true"); + t.is(v41.type(), Variant::type_boolean, "1234567890 > 42 --> boolean"); + t.is(v41.get_bool(), true, "1234567890 > 42 --> true"); Variant v42 = v4 > v2; - t.is (v42.type (), Variant::type_boolean, "1234567890 > 3.14 --> boolean"); - t.is (v42.get_bool (), true, "1234567890 > 3.14 --> true"); + t.is(v42.type(), Variant::type_boolean, "1234567890 > 3.14 --> boolean"); + t.is(v42.get_bool(), true, "1234567890 > 3.14 --> true"); Variant v43 = v4 > v3; - t.is (v43.type (), Variant::type_boolean, "1234567890 > 'foo' --> boolean"); - t.is (v43.get_bool (), true, "1234567890 > 'foo' --> true"); + t.is(v43.type(), Variant::type_boolean, "1234567890 > 'foo' --> boolean"); + t.is(v43.get_bool(), true, "1234567890 > 'foo' --> true"); Variant v44 = v4 > v4; - t.is (v44.type (), Variant::type_boolean, "1234567890 > 1234567890 --> boolean"); - t.is (v44.get_bool (), false, "1234567890 > 1234567890 --> false"); + t.is(v44.type(), Variant::type_boolean, "1234567890 > 1234567890 --> boolean"); + t.is(v44.get_bool(), false, "1234567890 > 1234567890 --> false"); Variant v45 = v4 > v5; // 1234567890 corresponds to Fri Feb 13 06:31:30 PM EST 2009 hence 1200 // (evaluated as now+1200s) be in future for any date after 2009-02-13 - t.is (v45.type (), Variant::type_boolean, "1234567890 > 1200 --> boolean"); - t.is (v45.get_bool (), false, "1234567890 > 1200 --> false"); + t.is(v45.type(), Variant::type_boolean, "1234567890 > 1200 --> boolean"); + t.is(v45.get_bool(), false, "1234567890 > 1200 --> false"); Variant v50 = v5 > v0; - t.is (v50.type (), Variant::type_boolean, "1200 > true --> boolean"); - t.is (v50.get_bool (), true, "1200 > true --> true"); + t.is(v50.type(), Variant::type_boolean, "1200 > true --> boolean"); + t.is(v50.get_bool(), true, "1200 > true --> true"); Variant v51 = v5 > v1; - t.is (v51.type (), Variant::type_boolean, "1200 > 42 --> boolean"); - t.is (v51.get_bool (), true, "1200 > 42 --> true"); + t.is(v51.type(), Variant::type_boolean, "1200 > 42 --> boolean"); + t.is(v51.get_bool(), true, "1200 > 42 --> true"); Variant v52 = v5 > v2; - t.is (v52.type (), Variant::type_boolean, "1200 > 3.14 --> boolean"); - t.is (v52.get_bool (), true, "1200 > 3.14 --> true"); + t.is(v52.type(), Variant::type_boolean, "1200 > 3.14 --> boolean"); + t.is(v52.get_bool(), true, "1200 > 3.14 --> true"); Variant v53 = v5 > v3; - t.is (v53.type (), Variant::type_boolean, "1200 > 'foo' --> boolean"); - t.is (v53.get_bool (), true, "1200 > 'foo' --> true"); + t.is(v53.type(), Variant::type_boolean, "1200 > 'foo' --> boolean"); + t.is(v53.get_bool(), true, "1200 > 'foo' --> true"); Variant v54 = v5 > v4; // Same reasoning as v45 - t.is (v54.type (), Variant::type_boolean, "1200 > 1234567890 --> boolean"); - t.is (v54.get_bool (), true, "1200 > 1234567890 --> true"); + t.is(v54.type(), Variant::type_boolean, "1200 > 1234567890 --> boolean"); + t.is(v54.get_bool(), true, "1200 > 1234567890 --> true"); Variant v55 = v5 > v5; - t.is (v55.type (), Variant::type_boolean, "1200 > 1200 --> boolean"); - t.is (v55.get_bool (), false, "1200 > 1200 --> false"); + t.is(v55.type(), Variant::type_boolean, "1200 > 1200 --> boolean"); + t.is(v55.get_bool(), false, "1200 > 1200 --> false"); return 0; } diff --git a/test/variant_gte.test.cpp b/test/variant_gte.test.cpp index 708a598e1..6da52047e 100644 --- a/test/variant_gte.test.cpp +++ b/test/variant_gte.test.cpp @@ -27,168 +27,168 @@ #include // cmake.h include header must come first -#include -#include #include +#include + +#include //////////////////////////////////////////////////////////////////////////////// -int main (int, char**) -{ - UnitTest t (72); +int main(int, char**) { + UnitTest t(72); - Variant v0 (true); - Variant v1 (42); - Variant v2 (3.14); - Variant v3 ("foo"); - Variant v4 (1234567890, Variant::type_date); - Variant v5 (1200, Variant::type_duration); + Variant v0(true); + Variant v1(42); + Variant v2(3.14); + Variant v3("foo"); + Variant v4(1234567890, Variant::type_date); + Variant v5(1200, Variant::type_duration); Variant v00 = v0 >= v0; - t.is (v00.type (), Variant::type_boolean, "true >= true --> boolean"); - t.is (v00.get_bool (), true, "true >= true --> true"); + t.is(v00.type(), Variant::type_boolean, "true >= true --> boolean"); + t.is(v00.get_bool(), true, "true >= true --> true"); Variant v01 = v0 >= v1; - t.is (v01.type (), Variant::type_boolean, "true >= 42 --> boolean"); - t.is (v01.get_bool (), false, "true >= 42 --> false"); + t.is(v01.type(), Variant::type_boolean, "true >= 42 --> boolean"); + t.is(v01.get_bool(), false, "true >= 42 --> false"); Variant v02 = v0 >= v2; - t.is (v02.type (), Variant::type_boolean, "true >= 3.14 --> boolean"); - t.is (v02.get_bool (), false, "true >= 3.14 --> false"); + t.is(v02.type(), Variant::type_boolean, "true >= 3.14 --> boolean"); + t.is(v02.get_bool(), false, "true >= 3.14 --> false"); Variant v03 = v0 >= v3; - t.is (v03.type (), Variant::type_boolean, "true >= 'foo' --> boolean"); - t.is (v03.get_bool (), true, "true >= 'foo' --> true"); + t.is(v03.type(), Variant::type_boolean, "true >= 'foo' --> boolean"); + t.is(v03.get_bool(), true, "true >= 'foo' --> true"); Variant v04 = v0 >= v4; - t.is (v04.type (), Variant::type_boolean, "true >= 1234567890 --> boolean"); - t.is (v04.get_bool (), false, "true >= 1234567890 --> false"); + t.is(v04.type(), Variant::type_boolean, "true >= 1234567890 --> boolean"); + t.is(v04.get_bool(), false, "true >= 1234567890 --> false"); Variant v05 = v0 >= v5; - t.is (v05.type (), Variant::type_boolean, "true >= 1200 --> boolean"); - t.is (v05.get_bool (), false, "true >= 1200 --> false"); + t.is(v05.type(), Variant::type_boolean, "true >= 1200 --> boolean"); + t.is(v05.get_bool(), false, "true >= 1200 --> false"); Variant v10 = v1 >= v0; - t.is (v10.type (), Variant::type_boolean, "42 >= true --> boolean"); - t.is (v10.get_bool (), true, "42 >= true --> true"); + t.is(v10.type(), Variant::type_boolean, "42 >= true --> boolean"); + t.is(v10.get_bool(), true, "42 >= true --> true"); Variant v11 = v1 >= v1; - t.is (v11.type (), Variant::type_boolean, "42 >= 42 --> boolean"); - t.is (v11.get_bool (), true, "42 >= 42 --> true"); + t.is(v11.type(), Variant::type_boolean, "42 >= 42 --> boolean"); + t.is(v11.get_bool(), true, "42 >= 42 --> true"); Variant v12 = v1 >= v2; - t.is (v12.type (), Variant::type_boolean, "42 >= 3.14 --> boolean"); - t.is (v12.get_bool (), true, "42 >= 3.14 --> true"); + t.is(v12.type(), Variant::type_boolean, "42 >= 3.14 --> boolean"); + t.is(v12.get_bool(), true, "42 >= 3.14 --> true"); Variant v13 = v1 >= v3; - t.is (v13.type (), Variant::type_boolean, "42 >= 'foo' --> boolean"); - t.is (v13.get_bool (), false, "42 >= 'foo' --> false"); + t.is(v13.type(), Variant::type_boolean, "42 >= 'foo' --> boolean"); + t.is(v13.get_bool(), false, "42 >= 'foo' --> false"); Variant v14 = v1 >= v4; - t.is (v04.type (), Variant::type_boolean, "42 >= 1234567890 --> boolean"); - t.is (v04.get_bool (), false, "42 >= 1234567890 --> false"); + t.is(v04.type(), Variant::type_boolean, "42 >= 1234567890 --> boolean"); + t.is(v04.get_bool(), false, "42 >= 1234567890 --> false"); Variant v15 = v1 >= v5; - t.is (v15.type (), Variant::type_boolean, "42 >= 1200 --> boolean"); - t.is (v15.get_bool (), false, "42 >= 1200 --> false"); + t.is(v15.type(), Variant::type_boolean, "42 >= 1200 --> boolean"); + t.is(v15.get_bool(), false, "42 >= 1200 --> false"); Variant v20 = v2 >= v0; - t.is (v20.type (), Variant::type_boolean, "3.14 >= true --> boolean"); - t.is (v20.get_bool (), true, "3.14 >= true --> true"); + t.is(v20.type(), Variant::type_boolean, "3.14 >= true --> boolean"); + t.is(v20.get_bool(), true, "3.14 >= true --> true"); Variant v21 = v2 >= v1; - t.is (v21.type (), Variant::type_boolean, "3.14 >= 42 --> boolean"); - t.is (v21.get_bool (), false, "3.14 >= 42 --> false"); + t.is(v21.type(), Variant::type_boolean, "3.14 >= 42 --> boolean"); + t.is(v21.get_bool(), false, "3.14 >= 42 --> false"); Variant v22 = v2 >= v2; - t.is (v22.type (), Variant::type_boolean, "3.14 >= 3.14 --> boolean"); - t.is (v22.get_bool (), true, "3.14 >= 3.14 --> true"); + t.is(v22.type(), Variant::type_boolean, "3.14 >= 3.14 --> boolean"); + t.is(v22.get_bool(), true, "3.14 >= 3.14 --> true"); Variant v23 = v2 >= v3; - t.is (v23.type (), Variant::type_boolean, "3.14 >= 'foo' --> boolean"); - t.is (v23.get_bool (), false, "3.14 >= 'foo' --> false"); + t.is(v23.type(), Variant::type_boolean, "3.14 >= 'foo' --> boolean"); + t.is(v23.get_bool(), false, "3.14 >= 'foo' --> false"); Variant v24 = v2 >= v4; - t.is (v24.type (), Variant::type_boolean, "3.14 >= 1234567890 --> boolean"); - t.is (v24.get_bool (), false, "3.14 >= 1234567890 --> false"); + t.is(v24.type(), Variant::type_boolean, "3.14 >= 1234567890 --> boolean"); + t.is(v24.get_bool(), false, "3.14 >= 1234567890 --> false"); Variant v25 = v2 >= v5; - t.is (v25.type (), Variant::type_boolean, "3.14 >= 1200 --> boolean"); - t.is (v25.get_bool (), false, "3.14 >= 1200 --> false"); + t.is(v25.type(), Variant::type_boolean, "3.14 >= 1200 --> boolean"); + t.is(v25.get_bool(), false, "3.14 >= 1200 --> false"); Variant v30 = v3 >= v0; - t.is (v30.type (), Variant::type_boolean, "'foo' >= true --> boolean"); - t.is (v30.get_bool (), false, "'foo' >= true --> false"); + t.is(v30.type(), Variant::type_boolean, "'foo' >= true --> boolean"); + t.is(v30.get_bool(), false, "'foo' >= true --> false"); Variant v31 = v3 >= v1; - t.is (v31.type (), Variant::type_boolean, "'foo' >= 42 --> boolean"); - t.is (v31.get_bool (), true, "'foo' >= 42 --> true"); + t.is(v31.type(), Variant::type_boolean, "'foo' >= 42 --> boolean"); + t.is(v31.get_bool(), true, "'foo' >= 42 --> true"); Variant v32 = v3 >= v2; - t.is (v32.type (), Variant::type_boolean, "'foo' >= 3.14 --> boolean"); - t.is (v32.get_bool (), true, "'foo' >= 3.14 --> true"); + t.is(v32.type(), Variant::type_boolean, "'foo' >= 3.14 --> boolean"); + t.is(v32.get_bool(), true, "'foo' >= 3.14 --> true"); Variant v33 = v3 >= v3; - t.is (v33.type (), Variant::type_boolean, "'foo' >= 'foo' --> boolean"); - t.is (v33.get_bool (), true, "'foo' >= 'foo' --> true"); + t.is(v33.type(), Variant::type_boolean, "'foo' >= 'foo' --> boolean"); + t.is(v33.get_bool(), true, "'foo' >= 'foo' --> true"); Variant v34 = v3 >= v4; - t.is (v34.type (), Variant::type_boolean, "'foo' >= 1234567890 --> boolean"); - t.is (v34.get_bool (), false, "'foo' >= 1234567890 --> false"); + t.is(v34.type(), Variant::type_boolean, "'foo' >= 1234567890 --> boolean"); + t.is(v34.get_bool(), false, "'foo' >= 1234567890 --> false"); Variant v35 = v3 >= v5; - t.is (v35.type (), Variant::type_boolean, "'foo' >= 1200 --> boolean"); - t.is (v35.get_bool (), false, "'foo' >= 1200 --> false"); + t.is(v35.type(), Variant::type_boolean, "'foo' >= 1200 --> boolean"); + t.is(v35.get_bool(), false, "'foo' >= 1200 --> false"); Variant v40 = v4 >= v0; - t.is (v40.type (), Variant::type_boolean, "1234567890 >= true --> boolean"); - t.is (v40.get_bool (), true, "1234567890 >= true --> true"); + t.is(v40.type(), Variant::type_boolean, "1234567890 >= true --> boolean"); + t.is(v40.get_bool(), true, "1234567890 >= true --> true"); Variant v41 = v4 >= v1; - t.is (v41.type (), Variant::type_boolean, "1234567890 >= 42 --> boolean"); - t.is (v41.get_bool (), true, "1234567890 >= 42 --> true"); + t.is(v41.type(), Variant::type_boolean, "1234567890 >= 42 --> boolean"); + t.is(v41.get_bool(), true, "1234567890 >= 42 --> true"); Variant v42 = v4 >= v2; - t.is (v42.type (), Variant::type_boolean, "1234567890 >= 3.14 --> boolean"); - t.is (v42.get_bool (), true, "1234567890 >= 3.14 --> true"); + t.is(v42.type(), Variant::type_boolean, "1234567890 >= 3.14 --> boolean"); + t.is(v42.get_bool(), true, "1234567890 >= 3.14 --> true"); Variant v43 = v4 >= v3; - t.is (v43.type (), Variant::type_boolean, "1234567890 >= 'foo' --> boolean"); - t.is (v43.get_bool (), true, "1234567890 >= 'foo' --> true"); + t.is(v43.type(), Variant::type_boolean, "1234567890 >= 'foo' --> boolean"); + t.is(v43.get_bool(), true, "1234567890 >= 'foo' --> true"); Variant v44 = v4 >= v4; - t.is (v44.type (), Variant::type_boolean, "1234567890 >= 1234567890 --> boolean"); - t.is (v44.get_bool (), true, "1234567890 >= 1234567890 --> true"); + t.is(v44.type(), Variant::type_boolean, "1234567890 >= 1234567890 --> boolean"); + t.is(v44.get_bool(), true, "1234567890 >= 1234567890 --> true"); Variant v45 = v4 >= v5; // 1234567890 corresponds to Fri Feb 13 06:31:30 PM EST 2009 hence 1200 // (evaluated as now+1200s) be in future for any date after 2009-02-13 - t.is (v45.type (), Variant::type_boolean, "1234567890 >= 1200 --> boolean"); - t.is (v45.get_bool (), false, "1234567890 >= 1200 --> false"); + t.is(v45.type(), Variant::type_boolean, "1234567890 >= 1200 --> boolean"); + t.is(v45.get_bool(), false, "1234567890 >= 1200 --> false"); Variant v50 = v5 >= v0; - t.is (v50.type (), Variant::type_boolean, "1200 >= true --> boolean"); - t.is (v50.get_bool (), true, "1200 >= true --> true"); + t.is(v50.type(), Variant::type_boolean, "1200 >= true --> boolean"); + t.is(v50.get_bool(), true, "1200 >= true --> true"); Variant v51 = v5 >= v1; - t.is (v51.type (), Variant::type_boolean, "1200 >= 42 --> boolean"); - t.is (v51.get_bool (), true, "1200 >= 42 --> true"); + t.is(v51.type(), Variant::type_boolean, "1200 >= 42 --> boolean"); + t.is(v51.get_bool(), true, "1200 >= 42 --> true"); Variant v52 = v5 >= v2; - t.is (v52.type (), Variant::type_boolean, "1200 >= 3.14 --> boolean"); - t.is (v52.get_bool (), true, "1200 >= 3.14 --> true"); + t.is(v52.type(), Variant::type_boolean, "1200 >= 3.14 --> boolean"); + t.is(v52.get_bool(), true, "1200 >= 3.14 --> true"); Variant v53 = v5 >= v3; - t.is (v53.type (), Variant::type_boolean, "1200 >= 'foo' --> boolean"); - t.is (v53.get_bool (), true, "1200 >= 'foo' --> true"); + t.is(v53.type(), Variant::type_boolean, "1200 >= 'foo' --> boolean"); + t.is(v53.get_bool(), true, "1200 >= 'foo' --> true"); Variant v54 = v5 >= v4; // Same reasoning as v45 - t.is (v54.type (), Variant::type_boolean, "1200 >= 1234567890 --> boolean"); - t.is (v54.get_bool (), true, "1200 >= 1234567890 --> true"); + t.is(v54.type(), Variant::type_boolean, "1200 >= 1234567890 --> boolean"); + t.is(v54.get_bool(), true, "1200 >= 1234567890 --> true"); Variant v55 = v5 >= v5; - t.is (v55.type (), Variant::type_boolean, "1200 >= 1200 --> boolean"); - t.is (v55.get_bool (), true, "1200 >= 1200 --> true"); + t.is(v55.type(), Variant::type_boolean, "1200 >= 1200 --> boolean"); + t.is(v55.get_bool(), true, "1200 >= 1200 --> true"); return 0; } diff --git a/test/variant_inequal.test.cpp b/test/variant_inequal.test.cpp index 348b7b9a7..eb1dc0b20 100644 --- a/test/variant_inequal.test.cpp +++ b/test/variant_inequal.test.cpp @@ -27,165 +27,165 @@ #include // cmake.h include header must come first -#include -#include #include +#include + +#include //////////////////////////////////////////////////////////////////////////////// -int main (int, char**) -{ - UnitTest t (72); +int main(int, char**) { + UnitTest t(72); - Variant v0 (true); - Variant v1 (42); - Variant v2 (3.14); - Variant v3 ("foo"); - Variant v4 (1234567890, Variant::type_date); - Variant v5 (1200, Variant::type_duration); + Variant v0(true); + Variant v1(42); + Variant v2(3.14); + Variant v3("foo"); + Variant v4(1234567890, Variant::type_date); + Variant v5(1200, Variant::type_duration); Variant v00 = v0 != v0; - t.is (v00.type (), Variant::type_boolean, "true != true --> boolean"); - t.is (v00.get_bool (), false, "true != true --> false"); + t.is(v00.type(), Variant::type_boolean, "true != true --> boolean"); + t.is(v00.get_bool(), false, "true != true --> false"); Variant v01 = v0 != v1; - t.is (v01.type (), Variant::type_boolean, "true != 42 --> boolean"); - t.is (v01.get_bool (), true, "true != 42 --> true"); + t.is(v01.type(), Variant::type_boolean, "true != 42 --> boolean"); + t.is(v01.get_bool(), true, "true != 42 --> true"); Variant v02 = v0 != v2; - t.is (v02.type (), Variant::type_boolean, "true != 3.14 --> boolean"); - t.is (v02.get_bool (), true, "true != 3.14 --> true"); + t.is(v02.type(), Variant::type_boolean, "true != 3.14 --> boolean"); + t.is(v02.get_bool(), true, "true != 3.14 --> true"); Variant v03 = v0 != v3; - t.is (v03.type (), Variant::type_boolean, "true != 'foo' --> boolean"); - t.is (v03.get_bool (), true, "true != 'foo' --> true"); + t.is(v03.type(), Variant::type_boolean, "true != 'foo' --> boolean"); + t.is(v03.get_bool(), true, "true != 'foo' --> true"); Variant v04 = v0 != v4; - t.is (v04.type (), Variant::type_boolean, "true != 1234567890 --> boolean"); - t.is (v04.get_bool (), true, "true != 1234567890 --> true"); + t.is(v04.type(), Variant::type_boolean, "true != 1234567890 --> boolean"); + t.is(v04.get_bool(), true, "true != 1234567890 --> true"); Variant v05 = v0 != v5; - t.is (v05.type (), Variant::type_boolean, "true != 1200 --> boolean"); - t.is (v05.get_bool (), true, "true != 1200 --> true"); + t.is(v05.type(), Variant::type_boolean, "true != 1200 --> boolean"); + t.is(v05.get_bool(), true, "true != 1200 --> true"); Variant v10 = v1 != v0; - t.is (v10.type (), Variant::type_boolean, "42 != true --> boolean"); - t.is (v10.get_bool (), true, "42 != true --> true"); + t.is(v10.type(), Variant::type_boolean, "42 != true --> boolean"); + t.is(v10.get_bool(), true, "42 != true --> true"); Variant v11 = v1 != v1; - t.is (v11.type (), Variant::type_boolean, "42 != 42 --> boolean"); - t.is (v11.get_bool (), false, "42 != 42 --> false"); + t.is(v11.type(), Variant::type_boolean, "42 != 42 --> boolean"); + t.is(v11.get_bool(), false, "42 != 42 --> false"); Variant v12 = v1 != v2; - t.is (v12.type (), Variant::type_boolean, "42 != 3.14 --> boolean"); - t.is (v12.get_bool (), true, "42 != 3.14 --> true"); + t.is(v12.type(), Variant::type_boolean, "42 != 3.14 --> boolean"); + t.is(v12.get_bool(), true, "42 != 3.14 --> true"); Variant v13 = v1 != v3; - t.is (v13.type (), Variant::type_boolean, "42 != 'foo' --> boolean"); - t.is (v13.get_bool (), true, "42 != 'foo' --> true"); + t.is(v13.type(), Variant::type_boolean, "42 != 'foo' --> boolean"); + t.is(v13.get_bool(), true, "42 != 'foo' --> true"); Variant v14 = v1 != v4; - t.is (v04.type (), Variant::type_boolean, "42 != 1234567890 --> boolean"); - t.is (v04.get_bool (), true, "42 != 1234567890 --> true"); + t.is(v04.type(), Variant::type_boolean, "42 != 1234567890 --> boolean"); + t.is(v04.get_bool(), true, "42 != 1234567890 --> true"); Variant v15 = v1 != v5; - t.is (v15.type (), Variant::type_boolean, "42 != 1200 --> boolean"); - t.is (v15.get_bool (), true, "42 != 1200 --> true"); + t.is(v15.type(), Variant::type_boolean, "42 != 1200 --> boolean"); + t.is(v15.get_bool(), true, "42 != 1200 --> true"); Variant v20 = v2 != v0; - t.is (v20.type (), Variant::type_boolean, "3.14 != true --> boolean"); - t.is (v20.get_bool (), true, "3.14 != true --> true"); + t.is(v20.type(), Variant::type_boolean, "3.14 != true --> boolean"); + t.is(v20.get_bool(), true, "3.14 != true --> true"); Variant v21 = v2 != v1; - t.is (v21.type (), Variant::type_boolean, "3.14 != 42 --> boolean"); - t.is (v21.get_bool (), true, "3.14 != 42 --> true"); + t.is(v21.type(), Variant::type_boolean, "3.14 != 42 --> boolean"); + t.is(v21.get_bool(), true, "3.14 != 42 --> true"); Variant v22 = v2 != v2; - t.is (v22.type (), Variant::type_boolean, "3.14 != 3.14 --> boolean"); - t.is (v22.get_bool (), false, "3.14 != 3.14 --> false"); + t.is(v22.type(), Variant::type_boolean, "3.14 != 3.14 --> boolean"); + t.is(v22.get_bool(), false, "3.14 != 3.14 --> false"); Variant v23 = v2 != v3; - t.is (v23.type (), Variant::type_boolean, "3.14 != 'foo' --> boolean"); - t.is (v23.get_bool (), true, "3.14 != 'foo' --> true"); + t.is(v23.type(), Variant::type_boolean, "3.14 != 'foo' --> boolean"); + t.is(v23.get_bool(), true, "3.14 != 'foo' --> true"); Variant v24 = v2 != v4; - t.is (v24.type (), Variant::type_boolean, "3.14 != 1234567890 --> boolean"); - t.is (v24.get_bool (), true, "3.14 != 1234567890 --> true"); + t.is(v24.type(), Variant::type_boolean, "3.14 != 1234567890 --> boolean"); + t.is(v24.get_bool(), true, "3.14 != 1234567890 --> true"); Variant v25 = v2 != v5; - t.is (v25.type (), Variant::type_boolean, "3.14 != 1200 --> boolean"); - t.is (v25.get_bool (), true, "3.14 != 1200 --> true"); + t.is(v25.type(), Variant::type_boolean, "3.14 != 1200 --> boolean"); + t.is(v25.get_bool(), true, "3.14 != 1200 --> true"); Variant v30 = v3 != v0; - t.is (v30.type (), Variant::type_boolean, "'foo' != true --> boolean"); - t.is (v30.get_bool (), true, "'foo' != true --> true"); + t.is(v30.type(), Variant::type_boolean, "'foo' != true --> boolean"); + t.is(v30.get_bool(), true, "'foo' != true --> true"); Variant v31 = v3 != v1; - t.is (v31.type (), Variant::type_boolean, "'foo' != 42 --> boolean"); - t.is (v31.get_bool (), true, "'foo' != 42 --> true"); + t.is(v31.type(), Variant::type_boolean, "'foo' != 42 --> boolean"); + t.is(v31.get_bool(), true, "'foo' != 42 --> true"); Variant v32 = v3 != v2; - t.is (v32.type (), Variant::type_boolean, "'foo' != 3.14 --> boolean"); - t.is (v32.get_bool (), true, "'foo' != 3.14 --> true"); + t.is(v32.type(), Variant::type_boolean, "'foo' != 3.14 --> boolean"); + t.is(v32.get_bool(), true, "'foo' != 3.14 --> true"); Variant v33 = v3 != v3; - t.is (v33.type (), Variant::type_boolean, "'foo' != 'foo' --> boolean"); - t.is (v33.get_bool (), false, "'foo' != 'foo' --> false"); + t.is(v33.type(), Variant::type_boolean, "'foo' != 'foo' --> boolean"); + t.is(v33.get_bool(), false, "'foo' != 'foo' --> false"); Variant v34 = v3 != v4; - t.is (v34.type (), Variant::type_boolean, "'foo' != 1234567890 --> boolean"); - t.is (v34.get_bool (), true, "'foo' != 1234567890 --> true"); + t.is(v34.type(), Variant::type_boolean, "'foo' != 1234567890 --> boolean"); + t.is(v34.get_bool(), true, "'foo' != 1234567890 --> true"); Variant v35 = v3 != v5; - t.is (v35.type (), Variant::type_boolean, "'foo' != 1200 --> boolean"); - t.is (v35.get_bool (), true, "'foo' != 1200 --> true"); + t.is(v35.type(), Variant::type_boolean, "'foo' != 1200 --> boolean"); + t.is(v35.get_bool(), true, "'foo' != 1200 --> true"); Variant v40 = v4 != v0; - t.is (v40.type (), Variant::type_boolean, "1234567890 != true --> boolean"); - t.is (v40.get_bool (), true, "1234567890 != true --> true"); + t.is(v40.type(), Variant::type_boolean, "1234567890 != true --> boolean"); + t.is(v40.get_bool(), true, "1234567890 != true --> true"); Variant v41 = v4 != v1; - t.is (v41.type (), Variant::type_boolean, "1234567890 != 42 --> boolean"); - t.is (v41.get_bool (), true, "1234567890 != 42 --> true"); + t.is(v41.type(), Variant::type_boolean, "1234567890 != 42 --> boolean"); + t.is(v41.get_bool(), true, "1234567890 != 42 --> true"); Variant v42 = v4 != v2; - t.is (v42.type (), Variant::type_boolean, "1234567890 != 3.14 --> boolean"); - t.is (v42.get_bool (), true, "1234567890 != 3.14 --> true"); + t.is(v42.type(), Variant::type_boolean, "1234567890 != 3.14 --> boolean"); + t.is(v42.get_bool(), true, "1234567890 != 3.14 --> true"); Variant v43 = v4 != v3; - t.is (v43.type (), Variant::type_boolean, "1234567890 != 'foo' --> boolean"); - t.is (v43.get_bool (), true, "1234567890 != 'foo' --> true"); + t.is(v43.type(), Variant::type_boolean, "1234567890 != 'foo' --> boolean"); + t.is(v43.get_bool(), true, "1234567890 != 'foo' --> true"); Variant v44 = v4 != v4; - t.is (v44.type (), Variant::type_boolean, "1234567890 != 1234567890 --> boolean"); - t.is (v44.get_bool (), false, "1234567890 != 1234567890 --> false"); + t.is(v44.type(), Variant::type_boolean, "1234567890 != 1234567890 --> boolean"); + t.is(v44.get_bool(), false, "1234567890 != 1234567890 --> false"); Variant v45 = v4 != v5; - t.is (v45.type (), Variant::type_boolean, "1234567890 != 1200 --> boolean"); - t.is (v45.get_bool (), true, "1234567890 != 1200 --> true"); + t.is(v45.type(), Variant::type_boolean, "1234567890 != 1200 --> boolean"); + t.is(v45.get_bool(), true, "1234567890 != 1200 --> true"); Variant v50 = v5 != v0; - t.is (v50.type (), Variant::type_boolean, "1200 != true --> boolean"); - t.is (v50.get_bool (), true, "1200 != true --> true"); + t.is(v50.type(), Variant::type_boolean, "1200 != true --> boolean"); + t.is(v50.get_bool(), true, "1200 != true --> true"); Variant v51 = v5 != v1; - t.is (v51.type (), Variant::type_boolean, "1200 != 42 --> boolean"); - t.is (v51.get_bool (), true, "1200 != 42 --> true"); + t.is(v51.type(), Variant::type_boolean, "1200 != 42 --> boolean"); + t.is(v51.get_bool(), true, "1200 != 42 --> true"); Variant v52 = v5 != v2; - t.is (v52.type (), Variant::type_boolean, "1200 != 3.14 --> boolean"); - t.is (v52.get_bool (), true, "1200 != 3.14 --> true"); + t.is(v52.type(), Variant::type_boolean, "1200 != 3.14 --> boolean"); + t.is(v52.get_bool(), true, "1200 != 3.14 --> true"); Variant v53 = v5 != v3; - t.is (v53.type (), Variant::type_boolean, "1200 != 'foo' --> boolean"); - t.is (v53.get_bool (), true, "1200 != 'foo' --> true"); + t.is(v53.type(), Variant::type_boolean, "1200 != 'foo' --> boolean"); + t.is(v53.get_bool(), true, "1200 != 'foo' --> true"); Variant v54 = v5 != v4; - t.is (v04.type (), Variant::type_boolean, "1200 != 1234567890 --> boolean"); - t.is (v04.get_bool (), true, "1200 != 1234567890 --> true"); + t.is(v04.type(), Variant::type_boolean, "1200 != 1234567890 --> boolean"); + t.is(v04.get_bool(), true, "1200 != 1234567890 --> true"); Variant v55 = v5 != v5; - t.is (v55.type (), Variant::type_boolean, "1200 != 1200 --> boolean"); - t.is (v55.get_bool (), false, "1200 != 1200 --> false"); + t.is(v55.type(), Variant::type_boolean, "1200 != 1200 --> boolean"); + t.is(v55.get_bool(), false, "1200 != 1200 --> false"); return 0; } diff --git a/test/variant_lt.test.cpp b/test/variant_lt.test.cpp index 897168c44..f5ae1331c 100644 --- a/test/variant_lt.test.cpp +++ b/test/variant_lt.test.cpp @@ -27,168 +27,168 @@ #include // cmake.h include header must come first -#include -#include #include +#include + +#include //////////////////////////////////////////////////////////////////////////////// -int main (int, char**) -{ - UnitTest t (72); +int main(int, char**) { + UnitTest t(72); - Variant v0 (true); - Variant v1 (42); - Variant v2 (3.14); - Variant v3 ("foo"); - Variant v4 (1234567890, Variant::type_date); - Variant v5 (1200, Variant::type_duration); + Variant v0(true); + Variant v1(42); + Variant v2(3.14); + Variant v3("foo"); + Variant v4(1234567890, Variant::type_date); + Variant v5(1200, Variant::type_duration); Variant v00 = v0 < v0; - t.is (v00.type (), Variant::type_boolean, "true < true --> boolean"); - t.is (v00.get_bool (), false, "true < true --> false"); + t.is(v00.type(), Variant::type_boolean, "true < true --> boolean"); + t.is(v00.get_bool(), false, "true < true --> false"); Variant v01 = v0 < v1; - t.is (v01.type (), Variant::type_boolean, "true < 42 --> boolean"); - t.is (v01.get_bool (), true, "true < 42 --> true"); + t.is(v01.type(), Variant::type_boolean, "true < 42 --> boolean"); + t.is(v01.get_bool(), true, "true < 42 --> true"); Variant v02 = v0 < v2; - t.is (v02.type (), Variant::type_boolean, "true < 3.14 --> boolean"); - t.is (v02.get_bool (), true, "true < 3.14 --> true"); + t.is(v02.type(), Variant::type_boolean, "true < 3.14 --> boolean"); + t.is(v02.get_bool(), true, "true < 3.14 --> true"); Variant v03 = v0 < v3; - t.is (v03.type (), Variant::type_boolean, "true < 'foo' --> boolean"); - t.is (v03.get_bool (), false, "true < 'foo' --> false"); + t.is(v03.type(), Variant::type_boolean, "true < 'foo' --> boolean"); + t.is(v03.get_bool(), false, "true < 'foo' --> false"); Variant v04 = v0 < v4; - t.is (v04.type (), Variant::type_boolean, "true < 1234567890 --> boolean"); - t.is (v04.get_bool (), true, "true < 1234567890 --> true"); + t.is(v04.type(), Variant::type_boolean, "true < 1234567890 --> boolean"); + t.is(v04.get_bool(), true, "true < 1234567890 --> true"); Variant v05 = v0 < v5; - t.is (v05.type (), Variant::type_boolean, "true < 1200 --> boolean"); - t.is (v05.get_bool (), true, "true < 1200 --> true"); + t.is(v05.type(), Variant::type_boolean, "true < 1200 --> boolean"); + t.is(v05.get_bool(), true, "true < 1200 --> true"); Variant v10 = v1 < v0; - t.is (v10.type (), Variant::type_boolean, "42 < true --> boolean"); - t.is (v10.get_bool (), false, "42 < true --> false"); + t.is(v10.type(), Variant::type_boolean, "42 < true --> boolean"); + t.is(v10.get_bool(), false, "42 < true --> false"); Variant v11 = v1 < v1; - t.is (v11.type (), Variant::type_boolean, "42 < 42 --> boolean"); - t.is (v11.get_bool (), false, "42 < 42 --> false"); + t.is(v11.type(), Variant::type_boolean, "42 < 42 --> boolean"); + t.is(v11.get_bool(), false, "42 < 42 --> false"); Variant v12 = v1 < v2; - t.is (v12.type (), Variant::type_boolean, "42 < 3.14 --> boolean"); - t.is (v12.get_bool (), false, "42 < 3.14 --> false"); + t.is(v12.type(), Variant::type_boolean, "42 < 3.14 --> boolean"); + t.is(v12.get_bool(), false, "42 < 3.14 --> false"); Variant v13 = v1 < v3; - t.is (v13.type (), Variant::type_boolean, "42 < 'foo' --> boolean"); - t.is (v13.get_bool (), true, "42 < 'foo' --> true"); + t.is(v13.type(), Variant::type_boolean, "42 < 'foo' --> boolean"); + t.is(v13.get_bool(), true, "42 < 'foo' --> true"); Variant v14 = v1 < v4; - t.is (v04.type (), Variant::type_boolean, "42 < 1234567890 --> boolean"); - t.is (v04.get_bool (), true, "42 < 1234567890 --> true"); + t.is(v04.type(), Variant::type_boolean, "42 < 1234567890 --> boolean"); + t.is(v04.get_bool(), true, "42 < 1234567890 --> true"); Variant v15 = v1 < v5; - t.is (v15.type (), Variant::type_boolean, "42 < 1200 --> boolean"); - t.is (v15.get_bool (), true, "42 < 1200 --> true"); + t.is(v15.type(), Variant::type_boolean, "42 < 1200 --> boolean"); + t.is(v15.get_bool(), true, "42 < 1200 --> true"); Variant v20 = v2 < v0; - t.is (v20.type (), Variant::type_boolean, "3.14 < true --> boolean"); - t.is (v20.get_bool (), false, "3.14 < true --> false"); + t.is(v20.type(), Variant::type_boolean, "3.14 < true --> boolean"); + t.is(v20.get_bool(), false, "3.14 < true --> false"); Variant v21 = v2 < v1; - t.is (v21.type (), Variant::type_boolean, "3.14 < 42 --> boolean"); - t.is (v21.get_bool (), true, "3.14 < 42 --> true"); + t.is(v21.type(), Variant::type_boolean, "3.14 < 42 --> boolean"); + t.is(v21.get_bool(), true, "3.14 < 42 --> true"); Variant v22 = v2 < v2; - t.is (v22.type (), Variant::type_boolean, "3.14 < 3.14 --> boolean"); - t.is (v22.get_bool (), false, "3.14 < 3.14 --> false"); + t.is(v22.type(), Variant::type_boolean, "3.14 < 3.14 --> boolean"); + t.is(v22.get_bool(), false, "3.14 < 3.14 --> false"); Variant v23 = v2 < v3; - t.is (v23.type (), Variant::type_boolean, "3.14 < 'foo' --> boolean"); - t.is (v23.get_bool (), true, "3.14 < 'foo' --> true"); + t.is(v23.type(), Variant::type_boolean, "3.14 < 'foo' --> boolean"); + t.is(v23.get_bool(), true, "3.14 < 'foo' --> true"); Variant v24 = v2 < v4; - t.is (v24.type (), Variant::type_boolean, "3.14 < 1234567890 --> boolean"); - t.is (v24.get_bool (), true, "3.14 < 1234567890 --> true"); + t.is(v24.type(), Variant::type_boolean, "3.14 < 1234567890 --> boolean"); + t.is(v24.get_bool(), true, "3.14 < 1234567890 --> true"); Variant v25 = v2 < v5; - t.is (v25.type (), Variant::type_boolean, "3.14 < 1200 --> boolean"); - t.is (v25.get_bool (), true, "3.14 < 1200 --> true"); + t.is(v25.type(), Variant::type_boolean, "3.14 < 1200 --> boolean"); + t.is(v25.get_bool(), true, "3.14 < 1200 --> true"); Variant v30 = v3 < v0; - t.is (v30.type (), Variant::type_boolean, "'foo' < true --> boolean"); - t.is (v30.get_bool (), true, "'foo' < true --> true"); + t.is(v30.type(), Variant::type_boolean, "'foo' < true --> boolean"); + t.is(v30.get_bool(), true, "'foo' < true --> true"); Variant v31 = v3 < v1; - t.is (v31.type (), Variant::type_boolean, "'foo' < 42 --> boolean"); - t.is (v31.get_bool (), false, "'foo' < 42 --> false"); + t.is(v31.type(), Variant::type_boolean, "'foo' < 42 --> boolean"); + t.is(v31.get_bool(), false, "'foo' < 42 --> false"); Variant v32 = v3 < v2; - t.is (v32.type (), Variant::type_boolean, "'foo' < 3.14 --> boolean"); - t.is (v32.get_bool (), false, "'foo' < 3.14 --> false"); + t.is(v32.type(), Variant::type_boolean, "'foo' < 3.14 --> boolean"); + t.is(v32.get_bool(), false, "'foo' < 3.14 --> false"); Variant v33 = v3 < v3; - t.is (v33.type (), Variant::type_boolean, "'foo' < 'foo' --> boolean"); - t.is (v33.get_bool (), false, "'foo' < 'foo' --> false"); + t.is(v33.type(), Variant::type_boolean, "'foo' < 'foo' --> boolean"); + t.is(v33.get_bool(), false, "'foo' < 'foo' --> false"); Variant v34 = v3 < v4; - t.is (v34.type (), Variant::type_boolean, "'foo' < 1234567890 --> boolean"); - t.is (v34.get_bool (), true, "'foo' < 1234567890 --> true"); + t.is(v34.type(), Variant::type_boolean, "'foo' < 1234567890 --> boolean"); + t.is(v34.get_bool(), true, "'foo' < 1234567890 --> true"); Variant v35 = v3 < v5; - t.is (v35.type (), Variant::type_boolean, "'foo' < 1200 --> boolean"); - t.is (v35.get_bool (), true, "'foo' < 1200 --> true"); + t.is(v35.type(), Variant::type_boolean, "'foo' < 1200 --> boolean"); + t.is(v35.get_bool(), true, "'foo' < 1200 --> true"); Variant v40 = v4 < v0; - t.is (v40.type (), Variant::type_boolean, "1234567890 < true --> boolean"); - t.is (v40.get_bool (), false, "1234567890 < true --> false"); + t.is(v40.type(), Variant::type_boolean, "1234567890 < true --> boolean"); + t.is(v40.get_bool(), false, "1234567890 < true --> false"); Variant v41 = v4 < v1; - t.is (v41.type (), Variant::type_boolean, "1234567890 < 42 --> boolean"); - t.is (v41.get_bool (), false, "1234567890 < 42 --> false"); + t.is(v41.type(), Variant::type_boolean, "1234567890 < 42 --> boolean"); + t.is(v41.get_bool(), false, "1234567890 < 42 --> false"); Variant v42 = v4 < v2; - t.is (v42.type (), Variant::type_boolean, "1234567890 < 3.14 --> boolean"); - t.is (v42.get_bool (), false, "1234567890 < 3.14 --> false"); + t.is(v42.type(), Variant::type_boolean, "1234567890 < 3.14 --> boolean"); + t.is(v42.get_bool(), false, "1234567890 < 3.14 --> false"); Variant v43 = v4 < v3; - t.is (v43.type (), Variant::type_boolean, "1234567890 < 'foo' --> boolean"); - t.is (v43.get_bool (), false, "1234567890 < 'foo' --> false"); + t.is(v43.type(), Variant::type_boolean, "1234567890 < 'foo' --> boolean"); + t.is(v43.get_bool(), false, "1234567890 < 'foo' --> false"); Variant v44 = v4 < v4; - t.is (v44.type (), Variant::type_boolean, "1234567890 < 1234567890 --> boolean"); - t.is (v44.get_bool (), false, "1234567890 < 1234567890 --> false"); + t.is(v44.type(), Variant::type_boolean, "1234567890 < 1234567890 --> boolean"); + t.is(v44.get_bool(), false, "1234567890 < 1234567890 --> false"); Variant v45 = v4 < v5; // 1234567890 corresponds to Fri Feb 13 06:31:30 PM EST 2009 hence 1200 // (evaluated as now+1200s) be in future for any date after 2009-02-13 - t.is (v45.type (), Variant::type_boolean, "1234567890 < 1200 --> boolean"); - t.is (v45.get_bool (), true, "1234567890 < 1200 --> true"); + t.is(v45.type(), Variant::type_boolean, "1234567890 < 1200 --> boolean"); + t.is(v45.get_bool(), true, "1234567890 < 1200 --> true"); Variant v50 = v5 < v0; - t.is (v50.type (), Variant::type_boolean, "1200 < true --> boolean"); - t.is (v50.get_bool (), false, "1200 < true --> false"); + t.is(v50.type(), Variant::type_boolean, "1200 < true --> boolean"); + t.is(v50.get_bool(), false, "1200 < true --> false"); Variant v51 = v5 < v1; - t.is (v51.type (), Variant::type_boolean, "1200 < 42 --> boolean"); - t.is (v51.get_bool (), false, "1200 < 42 --> false"); + t.is(v51.type(), Variant::type_boolean, "1200 < 42 --> boolean"); + t.is(v51.get_bool(), false, "1200 < 42 --> false"); Variant v52 = v5 < v2; - t.is (v52.type (), Variant::type_boolean, "1200 < 3.14 --> boolean"); - t.is (v52.get_bool (), false, "1200 < 3.14 --> false"); + t.is(v52.type(), Variant::type_boolean, "1200 < 3.14 --> boolean"); + t.is(v52.get_bool(), false, "1200 < 3.14 --> false"); Variant v53 = v5 < v3; - t.is (v53.type (), Variant::type_boolean, "1200 < 'foo' --> boolean"); - t.is (v53.get_bool (), false, "1200 < 'foo' --> false"); + t.is(v53.type(), Variant::type_boolean, "1200 < 'foo' --> boolean"); + t.is(v53.get_bool(), false, "1200 < 'foo' --> false"); Variant v54 = v5 < v4; // Same logic as v45. - t.is (v54.type (), Variant::type_boolean, "1200 < 1234567890 --> boolean"); - t.is (v54.get_bool (), false, "1200 < 1234567890 --> false"); + t.is(v54.type(), Variant::type_boolean, "1200 < 1234567890 --> boolean"); + t.is(v54.get_bool(), false, "1200 < 1234567890 --> false"); Variant v55 = v5 < v5; - t.is (v55.type (), Variant::type_boolean, "1200 < 1200 --> boolean"); - t.is (v55.get_bool (), false, "1200 < 1200 --> false"); + t.is(v55.type(), Variant::type_boolean, "1200 < 1200 --> boolean"); + t.is(v55.get_bool(), false, "1200 < 1200 --> false"); return 0; } diff --git a/test/variant_lte.test.cpp b/test/variant_lte.test.cpp index 30eda6398..4b2eaba9a 100644 --- a/test/variant_lte.test.cpp +++ b/test/variant_lte.test.cpp @@ -27,165 +27,165 @@ #include // cmake.h include header must come first -#include -#include #include +#include + +#include //////////////////////////////////////////////////////////////////////////////// -int main (int, char**) -{ - UnitTest t (72); +int main(int, char**) { + UnitTest t(72); - Variant v0 (true); - Variant v1 (42); - Variant v2 (3.14); - Variant v3 ("foo"); - Variant v4 (1234567890, Variant::type_duration); - Variant v5 (1200, Variant::type_duration); + Variant v0(true); + Variant v1(42); + Variant v2(3.14); + Variant v3("foo"); + Variant v4(1234567890, Variant::type_duration); + Variant v5(1200, Variant::type_duration); Variant v00 = v0 <= v0; - t.is (v00.type (), Variant::type_boolean, "true <= true --> boolean"); - t.is (v00.get_bool (), true, "true <= true --> true"); + t.is(v00.type(), Variant::type_boolean, "true <= true --> boolean"); + t.is(v00.get_bool(), true, "true <= true --> true"); Variant v01 = v0 <= v1; - t.is (v01.type (), Variant::type_boolean, "true <= 42 --> boolean"); - t.is (v01.get_bool (), true, "true <= 42 --> true"); + t.is(v01.type(), Variant::type_boolean, "true <= 42 --> boolean"); + t.is(v01.get_bool(), true, "true <= 42 --> true"); Variant v02 = v0 <= v2; - t.is (v02.type (), Variant::type_boolean, "true <= 3.14 --> boolean"); - t.is (v02.get_bool (), true, "true <= 3.14 --> true"); + t.is(v02.type(), Variant::type_boolean, "true <= 3.14 --> boolean"); + t.is(v02.get_bool(), true, "true <= 3.14 --> true"); Variant v03 = v0 <= v3; - t.is (v03.type (), Variant::type_boolean, "true <= 'foo' --> boolean"); - t.is (v03.get_bool (), false, "true <= 'foo' --> false"); + t.is(v03.type(), Variant::type_boolean, "true <= 'foo' --> boolean"); + t.is(v03.get_bool(), false, "true <= 'foo' --> false"); Variant v04 = v0 <= v4; - t.is (v04.type (), Variant::type_boolean, "true <= 1234567890 --> boolean"); - t.is (v04.get_bool (), true, "true <= 1234567890 --> true"); + t.is(v04.type(), Variant::type_boolean, "true <= 1234567890 --> boolean"); + t.is(v04.get_bool(), true, "true <= 1234567890 --> true"); Variant v05 = v0 <= v5; - t.is (v05.type (), Variant::type_boolean, "true <= 1200 --> boolean"); - t.is (v05.get_bool (), true, "true <= 1200 --> true"); + t.is(v05.type(), Variant::type_boolean, "true <= 1200 --> boolean"); + t.is(v05.get_bool(), true, "true <= 1200 --> true"); Variant v10 = v1 <= v0; - t.is (v10.type (), Variant::type_boolean, "42 <= true --> boolean"); - t.is (v10.get_bool (), false, "42 <= true --> false"); + t.is(v10.type(), Variant::type_boolean, "42 <= true --> boolean"); + t.is(v10.get_bool(), false, "42 <= true --> false"); Variant v11 = v1 <= v1; - t.is (v11.type (), Variant::type_boolean, "42 <= 42 --> boolean"); - t.is (v11.get_bool (), true, "42 <= 42 --> true"); + t.is(v11.type(), Variant::type_boolean, "42 <= 42 --> boolean"); + t.is(v11.get_bool(), true, "42 <= 42 --> true"); Variant v12 = v1 <= v2; - t.is (v12.type (), Variant::type_boolean, "42 <= 3.14 --> boolean"); - t.is (v12.get_bool (), false, "42 <= 3.14 --> false"); + t.is(v12.type(), Variant::type_boolean, "42 <= 3.14 --> boolean"); + t.is(v12.get_bool(), false, "42 <= 3.14 --> false"); Variant v13 = v1 <= v3; - t.is (v13.type (), Variant::type_boolean, "42 <= 'foo' --> boolean"); - t.is (v13.get_bool (), true, "42 <= 'foo' --> true"); + t.is(v13.type(), Variant::type_boolean, "42 <= 'foo' --> boolean"); + t.is(v13.get_bool(), true, "42 <= 'foo' --> true"); Variant v14 = v1 <= v4; - t.is (v04.type (), Variant::type_boolean, "42 <= 1234567890 --> boolean"); - t.is (v04.get_bool (), true, "42 <= 1234567890 --> true"); + t.is(v04.type(), Variant::type_boolean, "42 <= 1234567890 --> boolean"); + t.is(v04.get_bool(), true, "42 <= 1234567890 --> true"); Variant v15 = v1 <= v5; - t.is (v15.type (), Variant::type_boolean, "42 <= 1200 --> boolean"); - t.is (v15.get_bool (), true, "42 <= 1200 --> true"); + t.is(v15.type(), Variant::type_boolean, "42 <= 1200 --> boolean"); + t.is(v15.get_bool(), true, "42 <= 1200 --> true"); Variant v20 = v2 <= v0; - t.is (v20.type (), Variant::type_boolean, "3.14 <= true --> boolean"); - t.is (v20.get_bool (), false, "3.14 <= true --> false"); + t.is(v20.type(), Variant::type_boolean, "3.14 <= true --> boolean"); + t.is(v20.get_bool(), false, "3.14 <= true --> false"); Variant v21 = v2 <= v1; - t.is (v21.type (), Variant::type_boolean, "3.14 <= 42 --> boolean"); - t.is (v21.get_bool (), true, "3.14 <= 42 --> true"); + t.is(v21.type(), Variant::type_boolean, "3.14 <= 42 --> boolean"); + t.is(v21.get_bool(), true, "3.14 <= 42 --> true"); Variant v22 = v2 <= v2; - t.is (v22.type (), Variant::type_boolean, "3.14 <= 3.14 --> boolean"); - t.is (v22.get_bool (), true, "3.14 <= 3.14 --> true"); + t.is(v22.type(), Variant::type_boolean, "3.14 <= 3.14 --> boolean"); + t.is(v22.get_bool(), true, "3.14 <= 3.14 --> true"); Variant v23 = v2 <= v3; - t.is (v23.type (), Variant::type_boolean, "3.14 <= 'foo' --> boolean"); - t.is (v23.get_bool (), true, "3.14 <= 'foo' --> true"); + t.is(v23.type(), Variant::type_boolean, "3.14 <= 'foo' --> boolean"); + t.is(v23.get_bool(), true, "3.14 <= 'foo' --> true"); Variant v24 = v2 <= v4; - t.is (v24.type (), Variant::type_boolean, "3.14 <= 1234567890 --> boolean"); - t.is (v24.get_bool (), true, "3.14 <= 1234567890 --> true"); + t.is(v24.type(), Variant::type_boolean, "3.14 <= 1234567890 --> boolean"); + t.is(v24.get_bool(), true, "3.14 <= 1234567890 --> true"); Variant v25 = v2 <= v5; - t.is (v25.type (), Variant::type_boolean, "3.14 <= 1200 --> boolean"); - t.is (v25.get_bool (), true, "3.14 <= 1200 --> true"); + t.is(v25.type(), Variant::type_boolean, "3.14 <= 1200 --> boolean"); + t.is(v25.get_bool(), true, "3.14 <= 1200 --> true"); Variant v30 = v3 <= v0; - t.is (v30.type (), Variant::type_boolean, "'foo' <= true --> boolean"); - t.is (v30.get_bool (), true, "'foo' <= true --> true"); + t.is(v30.type(), Variant::type_boolean, "'foo' <= true --> boolean"); + t.is(v30.get_bool(), true, "'foo' <= true --> true"); Variant v31 = v3 <= v1; - t.is (v31.type (), Variant::type_boolean, "'foo' <= 42 --> boolean"); - t.is (v31.get_bool (), false, "'foo' <= 42 --> false"); + t.is(v31.type(), Variant::type_boolean, "'foo' <= 42 --> boolean"); + t.is(v31.get_bool(), false, "'foo' <= 42 --> false"); Variant v32 = v3 <= v2; - t.is (v32.type (), Variant::type_boolean, "'foo' <= 3.14 --> boolean"); - t.is (v32.get_bool (), false, "'foo' <= 3.14 --> false"); + t.is(v32.type(), Variant::type_boolean, "'foo' <= 3.14 --> boolean"); + t.is(v32.get_bool(), false, "'foo' <= 3.14 --> false"); Variant v33 = v3 <= v3; - t.is (v33.type (), Variant::type_boolean, "'foo' <= 'foo' --> boolean"); - t.is (v33.get_bool (), true, "'foo' <= 'foo' --> true"); + t.is(v33.type(), Variant::type_boolean, "'foo' <= 'foo' --> boolean"); + t.is(v33.get_bool(), true, "'foo' <= 'foo' --> true"); Variant v34 = v3 <= v4; - t.is (v34.type (), Variant::type_boolean, "'foo' <= 1234567890 --> boolean"); - t.is (v34.get_bool (), true, "'foo' <= 1234567890 --> true"); + t.is(v34.type(), Variant::type_boolean, "'foo' <= 1234567890 --> boolean"); + t.is(v34.get_bool(), true, "'foo' <= 1234567890 --> true"); Variant v35 = v3 <= v5; - t.is (v35.type (), Variant::type_boolean, "'foo' <= 1200 --> boolean"); - t.is (v35.get_bool (), true, "'foo' <= 1200 --> true"); + t.is(v35.type(), Variant::type_boolean, "'foo' <= 1200 --> boolean"); + t.is(v35.get_bool(), true, "'foo' <= 1200 --> true"); Variant v40 = v4 <= v0; - t.is (v40.type (), Variant::type_boolean, "1234567890 <= true --> boolean"); - t.is (v40.get_bool (), false, "1234567890 <= true --> false"); + t.is(v40.type(), Variant::type_boolean, "1234567890 <= true --> boolean"); + t.is(v40.get_bool(), false, "1234567890 <= true --> false"); Variant v41 = v4 <= v1; - t.is (v41.type (), Variant::type_boolean, "1234567890 <= 42 --> boolean"); - t.is (v41.get_bool (), false, "1234567890 <= 42 --> false"); + t.is(v41.type(), Variant::type_boolean, "1234567890 <= 42 --> boolean"); + t.is(v41.get_bool(), false, "1234567890 <= 42 --> false"); Variant v42 = v4 <= v2; - t.is (v42.type (), Variant::type_boolean, "1234567890 <= 3.14 --> boolean"); - t.is (v42.get_bool (), false, "1234567890 <= 3.14 --> false"); + t.is(v42.type(), Variant::type_boolean, "1234567890 <= 3.14 --> boolean"); + t.is(v42.get_bool(), false, "1234567890 <= 3.14 --> false"); Variant v43 = v4 <= v3; - t.is (v43.type (), Variant::type_boolean, "1234567890 <= 'foo' --> boolean"); - t.is (v43.get_bool (), false, "1234567890 <= 'foo' --> false"); + t.is(v43.type(), Variant::type_boolean, "1234567890 <= 'foo' --> boolean"); + t.is(v43.get_bool(), false, "1234567890 <= 'foo' --> false"); Variant v44 = v4 <= v4; - t.is (v44.type (), Variant::type_boolean, "1234567890 <= 1234567890 --> boolean"); - t.is (v44.get_bool (), true, "1234567890 <= 1234567890 --> true"); + t.is(v44.type(), Variant::type_boolean, "1234567890 <= 1234567890 --> boolean"); + t.is(v44.get_bool(), true, "1234567890 <= 1234567890 --> true"); Variant v45 = v4 <= v5; - t.is (v45.type (), Variant::type_boolean, "1234567890 <= 1200 --> boolean"); - t.is (v45.get_bool (), false, "1234567890 <= 1200 --> false"); + t.is(v45.type(), Variant::type_boolean, "1234567890 <= 1200 --> boolean"); + t.is(v45.get_bool(), false, "1234567890 <= 1200 --> false"); Variant v50 = v5 <= v0; - t.is (v50.type (), Variant::type_boolean, "1200 <= true --> boolean"); - t.is (v50.get_bool (), false, "1200 <= true --> false"); + t.is(v50.type(), Variant::type_boolean, "1200 <= true --> boolean"); + t.is(v50.get_bool(), false, "1200 <= true --> false"); Variant v51 = v5 <= v1; - t.is (v51.type (), Variant::type_boolean, "1200 <= 42 --> boolean"); - t.is (v51.get_bool (), false, "1200 <= 42 --> false"); + t.is(v51.type(), Variant::type_boolean, "1200 <= 42 --> boolean"); + t.is(v51.get_bool(), false, "1200 <= 42 --> false"); Variant v52 = v5 <= v2; - t.is (v52.type (), Variant::type_boolean, "1200 <= 3.14 --> boolean"); - t.is (v52.get_bool (), false, "1200 <= 3.14 --> false"); + t.is(v52.type(), Variant::type_boolean, "1200 <= 3.14 --> boolean"); + t.is(v52.get_bool(), false, "1200 <= 3.14 --> false"); Variant v53 = v5 <= v3; - t.is (v53.type (), Variant::type_boolean, "1200 <= 'foo' --> boolean"); - t.is (v53.get_bool (), false, "1200 <= 'foo' --> false"); + t.is(v53.type(), Variant::type_boolean, "1200 <= 'foo' --> boolean"); + t.is(v53.get_bool(), false, "1200 <= 'foo' --> false"); Variant v54 = v5 <= v4; - t.is (v54.type (), Variant::type_boolean, "1200 <= 1234567890 --> boolean"); - t.is (v54.get_bool (), true, "1200 <= 1234567890 --> true"); + t.is(v54.type(), Variant::type_boolean, "1200 <= 1234567890 --> boolean"); + t.is(v54.get_bool(), true, "1200 <= 1234567890 --> true"); Variant v55 = v5 <= v5; - t.is (v55.type (), Variant::type_boolean, "1200 <= 1200 --> boolean"); - t.is (v55.get_bool (), true, "1200 <= 1200 --> true"); + t.is(v55.type(), Variant::type_boolean, "1200 <= 1200 --> boolean"); + t.is(v55.get_bool(), true, "1200 <= 1200 --> true"); return 0; } diff --git a/test/variant_match.test.cpp b/test/variant_match.test.cpp index 97a7f6432..2777eb551 100644 --- a/test/variant_match.test.cpp +++ b/test/variant_match.test.cpp @@ -27,271 +27,271 @@ #include // cmake.h include header must come first -#include -#include -#include #include +#include +#include + +#include Task task; //////////////////////////////////////////////////////////////////////////////// -int main (int, char**) -{ - UnitTest t (120); +int main(int, char**) { + UnitTest t(120); - Variant vs0 ("untrue"); // ~ true - Variant vs1 (8421); // ~ 42 - Variant vs2 (3.14159); // ~ 3.14 - Variant vs3 ("foolish"); // ~ foo + Variant vs0("untrue"); // ~ true + Variant vs1(8421); // ~ 42 + Variant vs2(3.14159); // ~ 3.14 + Variant vs3("foolish"); // ~ foo - Variant v0 (true); - Variant v1 (42); - Variant v2 (3.14); - Variant v3 ("foo"); - Variant v4 (1234567890, Variant::type_date); - Variant v5 (1200, Variant::type_duration); + Variant v0(true); + Variant v1(42); + Variant v2(3.14); + Variant v3("foo"); + Variant v4(1234567890, Variant::type_date); + Variant v5(1200, Variant::type_duration); // Interesting cases. - Variant vs00 = vs0.operator_match (v0, task); - t.is (vs00.type (), Variant::type_boolean, "untrue ~ true --> boolean"); - t.is (vs00.get_bool (), true, "untrue ~ true --> true"); + Variant vs00 = vs0.operator_match(v0, task); + t.is(vs00.type(), Variant::type_boolean, "untrue ~ true --> boolean"); + t.is(vs00.get_bool(), true, "untrue ~ true --> true"); - Variant vs01 = vs0.operator_match (v1, task); - t.is (vs01.type (), Variant::type_boolean, "untrue ~ 42 --> boolean"); - t.is (vs01.get_bool (), false, "untrue ~ 42 --> false"); + Variant vs01 = vs0.operator_match(v1, task); + t.is(vs01.type(), Variant::type_boolean, "untrue ~ 42 --> boolean"); + t.is(vs01.get_bool(), false, "untrue ~ 42 --> false"); - Variant vs02 = vs0.operator_match (v2, task); - t.is (vs02.type (), Variant::type_boolean, "untrue ~ 3.14 --> boolean"); - t.is (vs02.get_bool (), false, "untrue ~ 3.14 --> false"); + Variant vs02 = vs0.operator_match(v2, task); + t.is(vs02.type(), Variant::type_boolean, "untrue ~ 3.14 --> boolean"); + t.is(vs02.get_bool(), false, "untrue ~ 3.14 --> false"); - Variant vs03 = vs0.operator_match (v3, task); - t.is (vs03.type (), Variant::type_boolean, "untrue ~ 'foo' --> boolean"); - t.is (vs03.get_bool (), false, "untrue ~ 'foo' --> false"); + Variant vs03 = vs0.operator_match(v3, task); + t.is(vs03.type(), Variant::type_boolean, "untrue ~ 'foo' --> boolean"); + t.is(vs03.get_bool(), false, "untrue ~ 'foo' --> false"); - Variant vs04 = vs0.operator_match (v4, task); - t.is (vs04.type (), Variant::type_boolean, "untrue ~ 1234567890 --> boolean"); - t.is (vs04.get_bool (), false, "untrue ~ 1234567890 --> false"); + Variant vs04 = vs0.operator_match(v4, task); + t.is(vs04.type(), Variant::type_boolean, "untrue ~ 1234567890 --> boolean"); + t.is(vs04.get_bool(), false, "untrue ~ 1234567890 --> false"); - Variant vs05 = vs0.operator_match (v5, task); - t.is (vs05.type (), Variant::type_boolean, "untrue ~ 1200 --> boolean"); - t.is (vs05.get_bool (), false, "untrue ~ 1200 --> false"); + Variant vs05 = vs0.operator_match(v5, task); + t.is(vs05.type(), Variant::type_boolean, "untrue ~ 1200 --> boolean"); + t.is(vs05.get_bool(), false, "untrue ~ 1200 --> false"); - Variant vs10 = vs1.operator_match (v0, task); - t.is (vs10.type (), Variant::type_boolean, "8421 ~ true --> boolean"); - t.is (vs10.get_bool (), false, "8421 ~ true --> false"); + Variant vs10 = vs1.operator_match(v0, task); + t.is(vs10.type(), Variant::type_boolean, "8421 ~ true --> boolean"); + t.is(vs10.get_bool(), false, "8421 ~ true --> false"); - Variant vs11 = vs1.operator_match (v1, task); - t.is (vs11.type (), Variant::type_boolean, "8421 ~ 42 --> boolean"); - t.is (vs11.get_bool (), true, "8421 ~ 42 --> true"); + Variant vs11 = vs1.operator_match(v1, task); + t.is(vs11.type(), Variant::type_boolean, "8421 ~ 42 --> boolean"); + t.is(vs11.get_bool(), true, "8421 ~ 42 --> true"); - Variant vs12 = vs1.operator_match (v2, task); - t.is (vs12.type (), Variant::type_boolean, "8421 ~ 3.14 --> boolean"); - t.is (vs12.get_bool (), false, "8421 ~ 3.14 --> false"); + Variant vs12 = vs1.operator_match(v2, task); + t.is(vs12.type(), Variant::type_boolean, "8421 ~ 3.14 --> boolean"); + t.is(vs12.get_bool(), false, "8421 ~ 3.14 --> false"); - Variant vs13 = vs1.operator_match (v3, task); - t.is (vs13.type (), Variant::type_boolean, "8421 ~ 'foo' --> boolean"); - t.is (vs13.get_bool (), false, "8421 ~ 'foo' --> false"); + Variant vs13 = vs1.operator_match(v3, task); + t.is(vs13.type(), Variant::type_boolean, "8421 ~ 'foo' --> boolean"); + t.is(vs13.get_bool(), false, "8421 ~ 'foo' --> false"); - Variant vs14 = vs1.operator_match (v4, task); - t.is (vs14.type (), Variant::type_boolean, "8421 ~ 1234567890 --> boolean"); - t.is (vs14.get_bool (), false, "8421 ~ 1234567890 --> false"); + Variant vs14 = vs1.operator_match(v4, task); + t.is(vs14.type(), Variant::type_boolean, "8421 ~ 1234567890 --> boolean"); + t.is(vs14.get_bool(), false, "8421 ~ 1234567890 --> false"); - Variant vs15 = vs1.operator_match (v5, task); - t.is (vs15.type (), Variant::type_boolean, "8421 ~ 1200 --> boolean"); - t.is (vs15.get_bool (), false, "8421 ~ 1200 --> false"); + Variant vs15 = vs1.operator_match(v5, task); + t.is(vs15.type(), Variant::type_boolean, "8421 ~ 1200 --> boolean"); + t.is(vs15.get_bool(), false, "8421 ~ 1200 --> false"); - Variant vs20 = vs2.operator_match (v0, task); - t.is (vs20.type (), Variant::type_boolean, "3.14159 ~ true --> boolean"); - t.is (vs20.get_bool (), false, "3.14159 ~ true --> false"); + Variant vs20 = vs2.operator_match(v0, task); + t.is(vs20.type(), Variant::type_boolean, "3.14159 ~ true --> boolean"); + t.is(vs20.get_bool(), false, "3.14159 ~ true --> false"); - Variant vs21 = vs2.operator_match (v1, task); - t.is (vs21.type (), Variant::type_boolean, "3.14159 ~ 42 --> boolean"); - t.is (vs21.get_bool (), false, "3.14159 ~ 42 --> false"); + Variant vs21 = vs2.operator_match(v1, task); + t.is(vs21.type(), Variant::type_boolean, "3.14159 ~ 42 --> boolean"); + t.is(vs21.get_bool(), false, "3.14159 ~ 42 --> false"); - Variant vs22 = vs2.operator_match (v2, task); - t.is (vs22.type (), Variant::type_boolean, "3.14159 ~ 3.14 --> boolean"); - t.is (vs22.get_bool (), true, "3.14159 ~ 3.14 --> true"); + Variant vs22 = vs2.operator_match(v2, task); + t.is(vs22.type(), Variant::type_boolean, "3.14159 ~ 3.14 --> boolean"); + t.is(vs22.get_bool(), true, "3.14159 ~ 3.14 --> true"); - Variant vs23 = vs2.operator_match (v3, task); - t.is (vs23.type (), Variant::type_boolean, "3.14159 ~ 'foo' --> boolean"); - t.is (vs23.get_bool (), false, "3.14159 ~ 'foo' --> false"); + Variant vs23 = vs2.operator_match(v3, task); + t.is(vs23.type(), Variant::type_boolean, "3.14159 ~ 'foo' --> boolean"); + t.is(vs23.get_bool(), false, "3.14159 ~ 'foo' --> false"); - Variant vs24 = vs2.operator_match (v4, task); - t.is (vs24.type (), Variant::type_boolean, "3.14159 ~ 1234567890 --> boolean"); - t.is (vs24.get_bool (), false, "3.14159 ~ 1234567890 --> false"); + Variant vs24 = vs2.operator_match(v4, task); + t.is(vs24.type(), Variant::type_boolean, "3.14159 ~ 1234567890 --> boolean"); + t.is(vs24.get_bool(), false, "3.14159 ~ 1234567890 --> false"); - Variant vs25 = vs2.operator_match (v5, task); - t.is (vs25.type (), Variant::type_boolean, "3.14159 ~ 1200 --> boolean"); - t.is (vs25.get_bool (), false, "3.14159 ~ 1200 --> false"); + Variant vs25 = vs2.operator_match(v5, task); + t.is(vs25.type(), Variant::type_boolean, "3.14159 ~ 1200 --> boolean"); + t.is(vs25.get_bool(), false, "3.14159 ~ 1200 --> false"); - Variant vs30 = vs3.operator_match (v0, task); - t.is (vs30.type (), Variant::type_boolean, "foolish ~ true --> boolean"); - t.is (vs30.get_bool (), false, "foolish ~ true --> false"); + Variant vs30 = vs3.operator_match(v0, task); + t.is(vs30.type(), Variant::type_boolean, "foolish ~ true --> boolean"); + t.is(vs30.get_bool(), false, "foolish ~ true --> false"); - Variant vs31 = vs3.operator_match (v1, task); - t.is (vs31.type (), Variant::type_boolean, "foolish ~ 42 --> boolean"); - t.is (vs31.get_bool (), false, "foolish ~ 42 --> false"); + Variant vs31 = vs3.operator_match(v1, task); + t.is(vs31.type(), Variant::type_boolean, "foolish ~ 42 --> boolean"); + t.is(vs31.get_bool(), false, "foolish ~ 42 --> false"); - Variant vs32 = vs3.operator_match (v2, task); - t.is (vs32.type (), Variant::type_boolean, "foolish ~ 3.14 --> boolean"); - t.is (vs32.get_bool (), false, "foolish ~ 3.14 --> false"); + Variant vs32 = vs3.operator_match(v2, task); + t.is(vs32.type(), Variant::type_boolean, "foolish ~ 3.14 --> boolean"); + t.is(vs32.get_bool(), false, "foolish ~ 3.14 --> false"); - Variant vs33 = vs3.operator_match (v3, task); - t.is (vs33.type (), Variant::type_boolean, "foolish ~ 'foo' --> boolean"); - t.is (vs33.get_bool (), true, "foolish ~ 'foo' --> true"); + Variant vs33 = vs3.operator_match(v3, task); + t.is(vs33.type(), Variant::type_boolean, "foolish ~ 'foo' --> boolean"); + t.is(vs33.get_bool(), true, "foolish ~ 'foo' --> true"); - Variant vs34 = vs3.operator_match (v4, task); - t.is (vs34.type (), Variant::type_boolean, "foolish ~ 1234567890 --> boolean"); - t.is (vs34.get_bool (), false, "foolish ~ 1234567890 --> false"); + Variant vs34 = vs3.operator_match(v4, task); + t.is(vs34.type(), Variant::type_boolean, "foolish ~ 1234567890 --> boolean"); + t.is(vs34.get_bool(), false, "foolish ~ 1234567890 --> false"); - Variant vs35 = vs3.operator_match (v5, task); - t.is (vs35.type (), Variant::type_boolean, "foolish ~ 1200 --> boolean"); - t.is (vs35.get_bool (), false, "foolish ~ 1200 --> false"); + Variant vs35 = vs3.operator_match(v5, task); + t.is(vs35.type(), Variant::type_boolean, "foolish ~ 1200 --> boolean"); + t.is(vs35.get_bool(), false, "foolish ~ 1200 --> false"); // Exhaustive comparisons. - Variant v00 = v0.operator_match (v0, task); - t.is (v00.type (), Variant::type_boolean, "true ~ true --> boolean"); - t.is (v00.get_bool (), true, "true ~ true --> true"); + Variant v00 = v0.operator_match(v0, task); + t.is(v00.type(), Variant::type_boolean, "true ~ true --> boolean"); + t.is(v00.get_bool(), true, "true ~ true --> true"); - Variant v01 = v0.operator_match (v1, task); - t.is (v01.type (), Variant::type_boolean, "true ~ 42 --> boolean"); - t.is (v01.get_bool (), false, "true ~ 42 --> false"); + Variant v01 = v0.operator_match(v1, task); + t.is(v01.type(), Variant::type_boolean, "true ~ 42 --> boolean"); + t.is(v01.get_bool(), false, "true ~ 42 --> false"); - Variant v02 = v0.operator_match (v2, task); - t.is (v02.type (), Variant::type_boolean, "true ~ 3.14 --> boolean"); - t.is (v02.get_bool (), false, "true ~ 3.14 --> false"); + Variant v02 = v0.operator_match(v2, task); + t.is(v02.type(), Variant::type_boolean, "true ~ 3.14 --> boolean"); + t.is(v02.get_bool(), false, "true ~ 3.14 --> false"); - Variant v03 = v0.operator_match (v3, task); - t.is (v03.type (), Variant::type_boolean, "true ~ 'foo' --> boolean"); - t.is (v03.get_bool (), false, "true ~ 'foo' --> false"); + Variant v03 = v0.operator_match(v3, task); + t.is(v03.type(), Variant::type_boolean, "true ~ 'foo' --> boolean"); + t.is(v03.get_bool(), false, "true ~ 'foo' --> false"); - Variant v04 = v0.operator_match (v4, task); - t.is (v04.type (), Variant::type_boolean, "true ~ 1234567890 --> boolean"); - t.is (v04.get_bool (), false, "true ~ 1234567890 --> false"); + Variant v04 = v0.operator_match(v4, task); + t.is(v04.type(), Variant::type_boolean, "true ~ 1234567890 --> boolean"); + t.is(v04.get_bool(), false, "true ~ 1234567890 --> false"); - Variant v05 = v0.operator_match (v5, task); - t.is (v05.type (), Variant::type_boolean, "true ~ 1200 --> boolean"); - t.is (v05.get_bool (), false, "true ~ 1200 --> false"); + Variant v05 = v0.operator_match(v5, task); + t.is(v05.type(), Variant::type_boolean, "true ~ 1200 --> boolean"); + t.is(v05.get_bool(), false, "true ~ 1200 --> false"); - Variant v10 = v1.operator_match (v0, task); - t.is (v10.type (), Variant::type_boolean, "42 ~ true --> boolean"); - t.is (v10.get_bool (), false, "42 ~ true --> false"); + Variant v10 = v1.operator_match(v0, task); + t.is(v10.type(), Variant::type_boolean, "42 ~ true --> boolean"); + t.is(v10.get_bool(), false, "42 ~ true --> false"); - Variant v11 = v1.operator_match (v1, task); - t.is (v11.type (), Variant::type_boolean, "42 ~ 42 --> boolean"); - t.is (v11.get_bool (), true, "42 ~ 42 --> true"); + Variant v11 = v1.operator_match(v1, task); + t.is(v11.type(), Variant::type_boolean, "42 ~ 42 --> boolean"); + t.is(v11.get_bool(), true, "42 ~ 42 --> true"); - Variant v12 = v1.operator_match (v2, task); - t.is (v12.type (), Variant::type_boolean, "42 ~ 3.14 --> boolean"); - t.is (v12.get_bool (), false, "42 ~ 3.14 --> false"); + Variant v12 = v1.operator_match(v2, task); + t.is(v12.type(), Variant::type_boolean, "42 ~ 3.14 --> boolean"); + t.is(v12.get_bool(), false, "42 ~ 3.14 --> false"); - Variant v13 = v1.operator_match (v3, task); - t.is (v13.type (), Variant::type_boolean, "42 ~ 'foo' --> boolean"); - t.is (v13.get_bool (), false, "42 ~ 'foo' --> false"); + Variant v13 = v1.operator_match(v3, task); + t.is(v13.type(), Variant::type_boolean, "42 ~ 'foo' --> boolean"); + t.is(v13.get_bool(), false, "42 ~ 'foo' --> false"); - Variant v14 = v1.operator_match (v4, task); - t.is (v04.type (), Variant::type_boolean, "42 ~ 1234567890 --> boolean"); - t.is (v04.get_bool (), false, "42 ~ 1234567890 --> false"); + Variant v14 = v1.operator_match(v4, task); + t.is(v04.type(), Variant::type_boolean, "42 ~ 1234567890 --> boolean"); + t.is(v04.get_bool(), false, "42 ~ 1234567890 --> false"); - Variant v15 = v1.operator_match (v5, task); - t.is (v15.type (), Variant::type_boolean, "42 ~ 1200 --> boolean"); - t.is (v15.get_bool (), false, "42 ~ 1200 --> false"); + Variant v15 = v1.operator_match(v5, task); + t.is(v15.type(), Variant::type_boolean, "42 ~ 1200 --> boolean"); + t.is(v15.get_bool(), false, "42 ~ 1200 --> false"); - Variant v20 = v2.operator_match (v0, task); - t.is (v20.type (), Variant::type_boolean, "3.14 ~ true --> boolean"); - t.is (v20.get_bool (), false, "3.14 ~ true --> false"); + Variant v20 = v2.operator_match(v0, task); + t.is(v20.type(), Variant::type_boolean, "3.14 ~ true --> boolean"); + t.is(v20.get_bool(), false, "3.14 ~ true --> false"); - Variant v21 = v2.operator_match (v1, task); - t.is (v21.type (), Variant::type_boolean, "3.14 ~ 42 --> boolean"); - t.is (v21.get_bool (), false, "3.14 ~ 42 --> false"); + Variant v21 = v2.operator_match(v1, task); + t.is(v21.type(), Variant::type_boolean, "3.14 ~ 42 --> boolean"); + t.is(v21.get_bool(), false, "3.14 ~ 42 --> false"); - Variant v22 = v2.operator_match (v2, task); - t.is (v22.type (), Variant::type_boolean, "3.14 ~ 3.14 --> boolean"); - t.is (v22.get_bool (), true, "3.14 ~ 3.14 --> true"); + Variant v22 = v2.operator_match(v2, task); + t.is(v22.type(), Variant::type_boolean, "3.14 ~ 3.14 --> boolean"); + t.is(v22.get_bool(), true, "3.14 ~ 3.14 --> true"); - Variant v23 = v2.operator_match (v3, task); - t.is (v23.type (), Variant::type_boolean, "3.14 ~ 'foo' --> boolean"); - t.is (v23.get_bool (), false, "3.14 ~ 'foo' --> false"); + Variant v23 = v2.operator_match(v3, task); + t.is(v23.type(), Variant::type_boolean, "3.14 ~ 'foo' --> boolean"); + t.is(v23.get_bool(), false, "3.14 ~ 'foo' --> false"); - Variant v24 = v2.operator_match (v4, task); - t.is (v24.type (), Variant::type_boolean, "3.14 ~ 1234567890 --> boolean"); - t.is (v24.get_bool (), false, "3.14 ~ 1234567890 --> false"); + Variant v24 = v2.operator_match(v4, task); + t.is(v24.type(), Variant::type_boolean, "3.14 ~ 1234567890 --> boolean"); + t.is(v24.get_bool(), false, "3.14 ~ 1234567890 --> false"); - Variant v25 = v2.operator_match (v5, task); - t.is (v25.type (), Variant::type_boolean, "3.14 ~ 1200 --> boolean"); - t.is (v25.get_bool (), false, "3.14 ~ 1200 --> false"); + Variant v25 = v2.operator_match(v5, task); + t.is(v25.type(), Variant::type_boolean, "3.14 ~ 1200 --> boolean"); + t.is(v25.get_bool(), false, "3.14 ~ 1200 --> false"); - Variant v30 = v3.operator_match (v0, task); - t.is (v30.type (), Variant::type_boolean, "'foo' ~ true --> boolean"); - t.is (v30.get_bool (), false, "'foo' ~ true --> false"); + Variant v30 = v3.operator_match(v0, task); + t.is(v30.type(), Variant::type_boolean, "'foo' ~ true --> boolean"); + t.is(v30.get_bool(), false, "'foo' ~ true --> false"); - Variant v31 = v3.operator_match (v1, task); - t.is (v31.type (), Variant::type_boolean, "'foo' ~ 42 --> boolean"); - t.is (v31.get_bool (), false, "'foo' ~ 42 --> false"); + Variant v31 = v3.operator_match(v1, task); + t.is(v31.type(), Variant::type_boolean, "'foo' ~ 42 --> boolean"); + t.is(v31.get_bool(), false, "'foo' ~ 42 --> false"); - Variant v32 = v3.operator_match (v2, task); - t.is (v32.type (), Variant::type_boolean, "'foo' ~ 3.14 --> boolean"); - t.is (v32.get_bool (), false, "'foo' ~ 3.14 --> false"); + Variant v32 = v3.operator_match(v2, task); + t.is(v32.type(), Variant::type_boolean, "'foo' ~ 3.14 --> boolean"); + t.is(v32.get_bool(), false, "'foo' ~ 3.14 --> false"); - Variant v33 = v3.operator_match (v3, task); - t.is (v33.type (), Variant::type_boolean, "'foo' ~ 'foo' --> boolean"); - t.is (v33.get_bool (), true, "'foo' ~ 'foo' --> true"); + Variant v33 = v3.operator_match(v3, task); + t.is(v33.type(), Variant::type_boolean, "'foo' ~ 'foo' --> boolean"); + t.is(v33.get_bool(), true, "'foo' ~ 'foo' --> true"); - Variant v34 = v3.operator_match (v4, task); - t.is (v34.type (), Variant::type_boolean, "'foo' ~ 1234567890 --> boolean"); - t.is (v34.get_bool (), false, "'foo' ~ 1234567890 --> false"); + Variant v34 = v3.operator_match(v4, task); + t.is(v34.type(), Variant::type_boolean, "'foo' ~ 1234567890 --> boolean"); + t.is(v34.get_bool(), false, "'foo' ~ 1234567890 --> false"); - Variant v35 = v3.operator_match (v5, task); - t.is (v35.type (), Variant::type_boolean, "'foo' ~ 1200 --> boolean"); - t.is (v35.get_bool (), false, "'foo' ~ 1200 --> false"); + Variant v35 = v3.operator_match(v5, task); + t.is(v35.type(), Variant::type_boolean, "'foo' ~ 1200 --> boolean"); + t.is(v35.get_bool(), false, "'foo' ~ 1200 --> false"); - Variant v40 = v4.operator_match (v0, task); - t.is (v40.type (), Variant::type_boolean, "1234567890 ~ true --> boolean"); - t.is (v40.get_bool (), false, "1234567890 ~ true --> false"); + Variant v40 = v4.operator_match(v0, task); + t.is(v40.type(), Variant::type_boolean, "1234567890 ~ true --> boolean"); + t.is(v40.get_bool(), false, "1234567890 ~ true --> false"); - Variant v41 = v4.operator_match (v1, task); - t.is (v41.type (), Variant::type_boolean, "1234567890 ~ 42 --> boolean"); - t.is (v41.get_bool (), false, "1234567890 ~ 42 --> false"); + Variant v41 = v4.operator_match(v1, task); + t.is(v41.type(), Variant::type_boolean, "1234567890 ~ 42 --> boolean"); + t.is(v41.get_bool(), false, "1234567890 ~ 42 --> false"); - Variant v42 = v4.operator_match (v2, task); - t.is (v42.type (), Variant::type_boolean, "1234567890 ~ 3.14 --> boolean"); - t.is (v42.get_bool (), false, "1234567890 ~ 3.14 --> false"); + Variant v42 = v4.operator_match(v2, task); + t.is(v42.type(), Variant::type_boolean, "1234567890 ~ 3.14 --> boolean"); + t.is(v42.get_bool(), false, "1234567890 ~ 3.14 --> false"); - Variant v43 = v4.operator_match (v3, task); - t.is (v43.type (), Variant::type_boolean, "1234567890 ~ 'foo' --> boolean"); - t.is (v43.get_bool (), false, "1234567890 ~ 'foo' --> false"); + Variant v43 = v4.operator_match(v3, task); + t.is(v43.type(), Variant::type_boolean, "1234567890 ~ 'foo' --> boolean"); + t.is(v43.get_bool(), false, "1234567890 ~ 'foo' --> false"); - Variant v44 = v4.operator_match (v4, task); - t.is (v44.type (), Variant::type_boolean, "1234567890 ~ 1234567890 --> boolean"); - t.is (v44.get_bool (), true, "1234567890 ~ 1234567890 --> true"); + Variant v44 = v4.operator_match(v4, task); + t.is(v44.type(), Variant::type_boolean, "1234567890 ~ 1234567890 --> boolean"); + t.is(v44.get_bool(), true, "1234567890 ~ 1234567890 --> true"); - Variant v45 = v4.operator_match (v5, task); - t.is (v45.type (), Variant::type_boolean, "1234567890 ~ 1200 --> boolean"); - t.is (v45.get_bool (), false, "1234567890 ~ 1200 --> false"); + Variant v45 = v4.operator_match(v5, task); + t.is(v45.type(), Variant::type_boolean, "1234567890 ~ 1200 --> boolean"); + t.is(v45.get_bool(), false, "1234567890 ~ 1200 --> false"); - Variant v50 = v5.operator_match (v0, task); - t.is (v50.type (), Variant::type_boolean, "1200 ~ true --> boolean"); - t.is (v50.get_bool (), false, "1200 ~ true --> false"); + Variant v50 = v5.operator_match(v0, task); + t.is(v50.type(), Variant::type_boolean, "1200 ~ true --> boolean"); + t.is(v50.get_bool(), false, "1200 ~ true --> false"); - Variant v51 = v5.operator_match (v1, task); - t.is (v51.type (), Variant::type_boolean, "1200 ~ 42 --> boolean"); - t.is (v51.get_bool (), false, "1200 ~ 42 --> false"); + Variant v51 = v5.operator_match(v1, task); + t.is(v51.type(), Variant::type_boolean, "1200 ~ 42 --> boolean"); + t.is(v51.get_bool(), false, "1200 ~ 42 --> false"); - Variant v52 = v5.operator_match (v2, task); - t.is (v52.type (), Variant::type_boolean, "1200 ~ 3.14 --> boolean"); - t.is (v52.get_bool (), false, "1200 ~ 3.14 --> false"); + Variant v52 = v5.operator_match(v2, task); + t.is(v52.type(), Variant::type_boolean, "1200 ~ 3.14 --> boolean"); + t.is(v52.get_bool(), false, "1200 ~ 3.14 --> false"); - Variant v53 = v5.operator_match (v3, task); - t.is (v53.type (), Variant::type_boolean, "1200 ~ 'foo' --> boolean"); - t.is (v53.get_bool (), false, "1200 ~ 'foo' --> false"); + Variant v53 = v5.operator_match(v3, task); + t.is(v53.type(), Variant::type_boolean, "1200 ~ 'foo' --> boolean"); + t.is(v53.get_bool(), false, "1200 ~ 'foo' --> false"); - Variant v54 = v5.operator_match (v4, task); - t.is (v04.type (), Variant::type_boolean, "1200 ~ 1234567890 --> boolean"); - t.is (v04.get_bool (), false, "1200 ~ 1234567890 --> false"); + Variant v54 = v5.operator_match(v4, task); + t.is(v04.type(), Variant::type_boolean, "1200 ~ 1234567890 --> boolean"); + t.is(v04.get_bool(), false, "1200 ~ 1234567890 --> false"); - Variant v55 = v5.operator_match (v5, task); - t.is (v55.type (), Variant::type_boolean, "1200 ~ 1200 --> boolean"); - t.is (v55.get_bool (), true, "1200 ~ 1200 --> true"); + Variant v55 = v5.operator_match(v5, task); + t.is(v55.type(), Variant::type_boolean, "1200 ~ 1200 --> boolean"); + t.is(v55.get_bool(), true, "1200 ~ 1200 --> true"); return 0; } diff --git a/test/variant_math.test.cpp b/test/variant_math.test.cpp index f247d4c69..417a13adc 100644 --- a/test/variant_math.test.cpp +++ b/test/variant_math.test.cpp @@ -27,20 +27,20 @@ #include // cmake.h include header must come first -#include -#include #include +#include + +#include #define EPSILON 0.001 //////////////////////////////////////////////////////////////////////////////// -int main (int, char**) -{ - UnitTest t (1); +int main(int, char**) { + UnitTest t(1); - Variant v0 (10.0); - v0.sqrt (); - t.is (v0.get_real (), 3.1622, EPSILON, "math sqrt 10 -> 3.1622"); + Variant v0(10.0); + v0.sqrt(); + t.is(v0.get_real(), 3.1622, EPSILON, "math sqrt 10 -> 3.1622"); return 0; } diff --git a/test/variant_modulo.test.cpp b/test/variant_modulo.test.cpp index 1f0e53c52..90a6da82c 100644 --- a/test/variant_modulo.test.cpp +++ b/test/variant_modulo.test.cpp @@ -27,171 +27,299 @@ #include // cmake.h include header must come first -#include -#include #include +#include + +#include #define EPSILON 0.0001 //////////////////////////////////////////////////////////////////////////////// -int main (int, char**) -{ - UnitTest t (40); +int main(int, char**) { + UnitTest t(40); - Variant v0 (true); - Variant v1 (42); - Variant v2 (3.14); - Variant v3 ("foo"); - Variant v4 (1234567890, Variant::type_date); - Variant v5 (1200, Variant::type_duration); + Variant v0(true); + Variant v1(42); + Variant v2(3.14); + Variant v3("foo"); + Variant v4(1234567890, Variant::type_date); + Variant v5(1200, Variant::type_duration); // boolean / boolean -> ERROR - try {Variant v00 = v0 % v0; t.fail ("true % true --> error");} - catch (...) {t.pass ("true % true --> error");} + try { + Variant v00 = v0 % v0; + t.fail("true % true --> error"); + } catch (...) { + t.pass("true % true --> error"); + } // boolean / integer -> ERROR - try {Variant v01 = v0 % v1; t.fail ("true % 42 --> error");} - catch (...) {t.pass ("true % 42 --> error");} + try { + Variant v01 = v0 % v1; + t.fail("true % 42 --> error"); + } catch (...) { + t.pass("true % 42 --> error"); + } // boolean / real -> ERROR - try {Variant v02 = v0 % v2; t.fail ("true % 3.14 --> error");} - catch (...) {t.pass ("true % 3.14 --> error");} + try { + Variant v02 = v0 % v2; + t.fail("true % 3.14 --> error"); + } catch (...) { + t.pass("true % 3.14 --> error"); + } // boolean / string -> ERROR - try {Variant v03 = v0 % v3; t.fail ("true % foo --> error");} - catch (...) {t.pass ("true % foo --> error");} + try { + Variant v03 = v0 % v3; + t.fail("true % foo --> error"); + } catch (...) { + t.pass("true % foo --> error"); + } // boolean / date -> ERROR - try {Variant v04 = v0 % v4; t.fail ("true % 1234567890 --> error");} - catch (...) {t.pass ("true % 1234567890 --> error");} + try { + Variant v04 = v0 % v4; + t.fail("true % 1234567890 --> error"); + } catch (...) { + t.pass("true % 1234567890 --> error"); + } // boolean / duration -> ERROR - try {Variant v05 = v0 % v5; t.fail ("true % 1200 --> error");} - catch (...) {t.pass ("true % 1200 --> error");} + try { + Variant v05 = v0 % v5; + t.fail("true % 1200 --> error"); + } catch (...) { + t.pass("true % 1200 --> error"); + } // integer / boolean -> ERROR - try {Variant v10 = v1 % v0; t.fail ("42 % true --> error");} - catch (...) {t.pass ("42 % true --> error");} + try { + Variant v10 = v1 % v0; + t.fail("42 % true --> error"); + } catch (...) { + t.pass("42 % true --> error"); + } // integer / integer -> integer Variant v11 = v1 % v1; - t.is (v11.type (), Variant::type_integer, "42 % 42 --> integer"); - t.is (v11.get_integer (), 0, "42 % 42 --> 0"); + t.is(v11.type(), Variant::type_integer, "42 % 42 --> integer"); + t.is(v11.get_integer(), 0, "42 % 42 --> 0"); // integer / real -> real Variant v12 = v1 % v2; - t.is (v12.type (), Variant::type_real, "42 % 3.14 --> real"); - t.is (v12.get_real (), 1.18, EPSILON, "42 % 3.14 --> 1.18"); + t.is(v12.type(), Variant::type_real, "42 % 3.14 --> real"); + t.is(v12.get_real(), 1.18, EPSILON, "42 % 3.14 --> 1.18"); // integer / string -> ERROR - try {Variant v13 = v1 % v3; t.fail ("42 % foo --> error");} - catch (...) {t.pass ("42 % foo --> error");} + try { + Variant v13 = v1 % v3; + t.fail("42 % foo --> error"); + } catch (...) { + t.pass("42 % foo --> error"); + } // integer / date -> ERROR - try {Variant v14 = v1 % v4; t.fail ("42 % 1234567890 --> error");} - catch (...) {t.pass ("42 % 1234567890 --> error");} + try { + Variant v14 = v1 % v4; + t.fail("42 % 1234567890 --> error"); + } catch (...) { + t.pass("42 % 1234567890 --> error"); + } // integer / duration -> duration - try {Variant v15 = v1 % v5; t.fail ("42 % 1200 --> error");} - catch (...) {t.pass ("42 % 1200 --> error");} + try { + Variant v15 = v1 % v5; + t.fail("42 % 1200 --> error"); + } catch (...) { + t.pass("42 % 1200 --> error"); + } // real / boolean -> ERROR - try {Variant v20 = v2 % v0; t.fail ("3.14 % true --> error");} - catch (...) {t.pass ("3.14 % true --> error");} + try { + Variant v20 = v2 % v0; + t.fail("3.14 % true --> error"); + } catch (...) { + t.pass("3.14 % true --> error"); + } // real / integer -> real Variant v21 = v2 % v1; - t.is (v21.type (), Variant::type_real, "3.14 % 42 --> real"); - t.is (v21.get_real (), 3.14, EPSILON, "3.14 % 42 --> 3.14"); + t.is(v21.type(), Variant::type_real, "3.14 % 42 --> real"); + t.is(v21.get_real(), 3.14, EPSILON, "3.14 % 42 --> 3.14"); // real / real -> real Variant v22 = v2 % v2; - t.is (v22.type (), Variant::type_real, "3.14 % 3.14 --> real"); - t.is (v22.get_real (), 0.0, EPSILON, "3.14 % 3.14 --> 0.0"); + t.is(v22.type(), Variant::type_real, "3.14 % 3.14 --> real"); + t.is(v22.get_real(), 0.0, EPSILON, "3.14 % 3.14 --> 0.0"); // real / string -> error - try {Variant v23 = v2 % v3; t.fail ("3.14 % foo --> error");} - catch (...) {t.pass ("3.14 % foo --> error");} + try { + Variant v23 = v2 % v3; + t.fail("3.14 % foo --> error"); + } catch (...) { + t.pass("3.14 % foo --> error"); + } // real / date -> error - try {Variant v24 = v2 % v4; t.fail ("3.14 % 1234567890 --> error");} - catch (...) {t.pass ("3.14 % 1234567890 --> error");} + try { + Variant v24 = v2 % v4; + t.fail("3.14 % 1234567890 --> error"); + } catch (...) { + t.pass("3.14 % 1234567890 --> error"); + } // real / duration -> duration - try {Variant v25 = v2 % v5; t.fail ("3.14 % 1200 --> error");} - catch (...) {t.pass ("3.14 % 1200 --> error");} + try { + Variant v25 = v2 % v5; + t.fail("3.14 % 1200 --> error"); + } catch (...) { + t.pass("3.14 % 1200 --> error"); + } // string / boolean -> ERROR - try {Variant v30 = v3 % v0; t.fail ("foo % true --> error");} - catch (...) {t.pass ("foo % true --> error");} + try { + Variant v30 = v3 % v0; + t.fail("foo % true --> error"); + } catch (...) { + t.pass("foo % true --> error"); + } // string / integer -> ERROR - try {Variant v31 = v3 % v1; t.fail ("foo % 42 --> error");} - catch (...) {t.pass ("foo % 42 --> error");} + try { + Variant v31 = v3 % v1; + t.fail("foo % 42 --> error"); + } catch (...) { + t.pass("foo % 42 --> error"); + } // string / real -> ERROR - try {Variant v32 = v3 % v2; t.fail ("foo % 3.14 --> error");} - catch (...) {t.pass ("foo % 3.14 --> error");} + try { + Variant v32 = v3 % v2; + t.fail("foo % 3.14 --> error"); + } catch (...) { + t.pass("foo % 3.14 --> error"); + } // string / string -> ERROR - try {Variant v33 = v3 % v3; t.fail ("foo % foo --> error");} - catch (...) {t.pass ("foo % foo --> error");} + try { + Variant v33 = v3 % v3; + t.fail("foo % foo --> error"); + } catch (...) { + t.pass("foo % foo --> error"); + } // string / date -> ERROR - try {Variant v34 = v3 % v4; t.fail ("foo % 1234567890 --> error");} - catch (...) {t.pass ("foo % 1234567890 --> error");} + try { + Variant v34 = v3 % v4; + t.fail("foo % 1234567890 --> error"); + } catch (...) { + t.pass("foo % 1234567890 --> error"); + } // string / duration -> ERROR - try {Variant v35 = v3 % v5; t.fail ("foo % 1200 --> error");} - catch (...) {t.pass ("foo % 1200 --> error");} + try { + Variant v35 = v3 % v5; + t.fail("foo % 1200 --> error"); + } catch (...) { + t.pass("foo % 1200 --> error"); + } // date / boolean -> ERROR - try {Variant v40 = v4 % v0; t.fail ("1234567890 % true --> error");} - catch (...) {t.pass ("1234567890 % true --> error");} + try { + Variant v40 = v4 % v0; + t.fail("1234567890 % true --> error"); + } catch (...) { + t.pass("1234567890 % true --> error"); + } // date / integer -> ERROR - try {Variant v41 = v4 % v1; t.fail ("1234567890 % 42 --> error");} - catch (...) {t.pass ("1234567890 % 42 --> error");} + try { + Variant v41 = v4 % v1; + t.fail("1234567890 % 42 --> error"); + } catch (...) { + t.pass("1234567890 % 42 --> error"); + } // date / real -> ERROR - try {Variant v42 = v4 % v2; t.fail ("1234567890 % 3.14 --> error");} - catch (...) {t.pass ("1234567890 % 3.14 --> error");} + try { + Variant v42 = v4 % v2; + t.fail("1234567890 % 3.14 --> error"); + } catch (...) { + t.pass("1234567890 % 3.14 --> error"); + } // date / string -> ERROR - try {Variant v43 = v4 % v3; t.fail ("1234567890 % foo --> error");} - catch (...) {t.pass ("1234567890 % foo --> error");} + try { + Variant v43 = v4 % v3; + t.fail("1234567890 % foo --> error"); + } catch (...) { + t.pass("1234567890 % foo --> error"); + } // date / date -> ERROR - try {Variant v44 = v4 % v4; t.fail ("1234567890 % 1234567890 --> error");} - catch (...) {t.pass ("1234567890 % 1234567890 --> error");} + try { + Variant v44 = v4 % v4; + t.fail("1234567890 % 1234567890 --> error"); + } catch (...) { + t.pass("1234567890 % 1234567890 --> error"); + } // date / duration -> ERROR - try {Variant v45 = v4 % v5; t.fail ("1234567890 % 1200 --> error");} - catch (...) {t.pass ("1234567890 % 1200 --> error");} + try { + Variant v45 = v4 % v5; + t.fail("1234567890 % 1200 --> error"); + } catch (...) { + t.pass("1234567890 % 1200 --> error"); + } // duration / boolean -> ERROR - try {Variant v50 = v5 % v0; t.fail ("1200 % true --> error");} - catch (...) {t.pass ("1200 % true --> error");} + try { + Variant v50 = v5 % v0; + t.fail("1200 % true --> error"); + } catch (...) { + t.pass("1200 % true --> error"); + } // duration / integer -> ERROR - try {Variant v51 = v5 % v1; t.fail ("1200 % 42 --> error");} - catch (...) {t.pass ("1200 % 42 --> error");} + try { + Variant v51 = v5 % v1; + t.fail("1200 % 42 --> error"); + } catch (...) { + t.pass("1200 % 42 --> error"); + } // duration / real -> ERROR - try {Variant v52 = v5 % v2; t.fail ("1200 % 3.14 --> error");} - catch (...) {t.pass ("1200 % 3.14 --> error");} + try { + Variant v52 = v5 % v2; + t.fail("1200 % 3.14 --> error"); + } catch (...) { + t.pass("1200 % 3.14 --> error"); + } // duration / string -> ERROR - try {Variant v53 = v5 % v3; t.fail ("1200 % foo --> error");} - catch (...) {t.pass ("1200 % foo --> error");} + try { + Variant v53 = v5 % v3; + t.fail("1200 % foo --> error"); + } catch (...) { + t.pass("1200 % foo --> error"); + } // duration / date -> ERROR - try {Variant v54 = v5 % v4; t.fail ("1200 % 1234567890 --> error");} - catch (...) {t.pass ("1200 % 1234567890 --> error");} + try { + Variant v54 = v5 % v4; + t.fail("1200 % 1234567890 --> error"); + } catch (...) { + t.pass("1200 % 1234567890 --> error"); + } // duration / duration -> ERROR - try {Variant v55 = v5 % v5; t.fail ("1200 % 1200 --> error");} - catch (...) {t.pass ("1200 % 1200 --> error");} + try { + Variant v55 = v5 % v5; + t.fail("1200 % 1200 --> error"); + } catch (...) { + t.pass("1200 % 1200 --> error"); + } return 0; } diff --git a/test/variant_multiply.test.cpp b/test/variant_multiply.test.cpp index 6dcb20159..6d253ecbe 100644 --- a/test/variant_multiply.test.cpp +++ b/test/variant_multiply.test.cpp @@ -27,186 +27,256 @@ #include // cmake.h include header must come first -#include -#include #include +#include + +#include #define EPSILON 0.0001 //////////////////////////////////////////////////////////////////////////////// -int main (int, char**) -{ - UnitTest t (54); +int main(int, char**) { + UnitTest t(54); - Variant v0 (true); - Variant v1 (42); - Variant v2 (3.14); - Variant v3 ("foo"); - Variant v4 (1234567890, Variant::type_date); - Variant v5 (1200, Variant::type_duration); + Variant v0(true); + Variant v1(42); + Variant v2(3.14); + Variant v3("foo"); + Variant v4(1234567890, Variant::type_date); + Variant v5(1200, Variant::type_duration); // boolean * boolean -> ERROR - try {Variant v00 = v0 * v0; t.fail ("true * true --> error");} - catch (...) {t.pass ("true * true --> error");} + try { + Variant v00 = v0 * v0; + t.fail("true * true --> error"); + } catch (...) { + t.pass("true * true --> error"); + } // boolean * integer -> integer Variant v01 = v0 * v1; - t.is (v01.type (), Variant::type_integer, "true * 42 --> integer"); - t.is (v01.get_integer (), 42, "true * 42 --> 42"); + t.is(v01.type(), Variant::type_integer, "true * 42 --> integer"); + t.is(v01.get_integer(), 42, "true * 42 --> 42"); // boolean * real -> real Variant v02 = v0 * v2; - t.is (v02.type (), Variant::type_real, "true * 3.14 --> real"); - t.is (v02.get_real (), 3.14, EPSILON, "true * 3.14 --> 3.14"); + t.is(v02.type(), Variant::type_real, "true * 3.14 --> real"); + t.is(v02.get_real(), 3.14, EPSILON, "true * 3.14 --> 3.14"); // boolean * string -> string Variant v03 = v0 * v3; - t.is (v03.type (), Variant::type_string, "true * foo --> real"); - t.is (v03.get_string (), "foo", "true * foo --> foo"); + t.is(v03.type(), Variant::type_string, "true * foo --> real"); + t.is(v03.get_string(), "foo", "true * foo --> foo"); // boolean * date -> ERROR - try {Variant v04 = v0 * v4; t.fail ("true * 1234567890 --> error");} - catch (...) {t.pass ("true * 1234567890 --> error");} + try { + Variant v04 = v0 * v4; + t.fail("true * 1234567890 --> error"); + } catch (...) { + t.pass("true * 1234567890 --> error"); + } // boolean * duration -> duration Variant v05 = v0 * v5; - t.is (v05.type (), Variant::type_duration, "true * 1200 --> duration"); - t.is (v05.get_duration (), 1200, "true * 1200 --> 1200"); + t.is(v05.type(), Variant::type_duration, "true * 1200 --> duration"); + t.is(v05.get_duration(), 1200, "true * 1200 --> 1200"); // integer * boolean -> integer Variant v10 = v1 * v0; - t.is (v10.type (), Variant::type_integer, "42 * true --> integer"); - t.is (v10.get_integer (), 42, "42 * true --> 42"); + t.is(v10.type(), Variant::type_integer, "42 * true --> integer"); + t.is(v10.get_integer(), 42, "42 * true --> 42"); // integer * integer -> integer Variant v11 = v1 * v1; - t.is (v11.type (), Variant::type_integer, "42 * 42 --> integer"); - t.is (v11.get_integer (), 1764, "42 * 42 --> 1764"); + t.is(v11.type(), Variant::type_integer, "42 * 42 --> integer"); + t.is(v11.get_integer(), 1764, "42 * 42 --> 1764"); // integer * real -> real Variant v12 = v1 * v2; - t.is (v12.type (), Variant::type_real, "42 * 3.14 --> real"); - t.is (v12.get_real (), 131.88, EPSILON, "42 * 3.14 --> 131.88"); + t.is(v12.type(), Variant::type_real, "42 * 3.14 --> real"); + t.is(v12.get_real(), 131.88, EPSILON, "42 * 3.14 --> 131.88"); // integer * string -> string Variant v13 = v1 * v3; - t.is (v13.type (), Variant::type_string, "42 * foo --> string"); - t.is (v13.get_string ().substr (0, 10), "foofoofoof", - "42 * foo --> foofoofoofoo..."); + t.is(v13.type(), Variant::type_string, "42 * foo --> string"); + t.is(v13.get_string().substr(0, 10), "foofoofoof", "42 * foo --> foofoofoofoo..."); // integer * date -> error - try {Variant v14 = v1 * v4; t.fail ("42 * 1234567890 --> error");} - catch (...) {t.pass ("42 * 1234567890 --> error");} + try { + Variant v14 = v1 * v4; + t.fail("42 * 1234567890 --> error"); + } catch (...) { + t.pass("42 * 1234567890 --> error"); + } // integer * duration -> duration Variant v15 = v1 * v5; - t.is (v15.type (), Variant::type_duration, "42 * 1200 --> duration"); - t.is (v15.get_duration (), 50400, "42 * 1200 --> 50400"); + t.is(v15.type(), Variant::type_duration, "42 * 1200 --> duration"); + t.is(v15.get_duration(), 50400, "42 * 1200 --> 50400"); // real * boolean -> real Variant v20 = v2 * v0; - t.is (v20.type (), Variant::type_real, "3.14 * true --> real"); - t.is (v20.get_real (), 3.14, EPSILON, "3.14 * true --> 3.14"); + t.is(v20.type(), Variant::type_real, "3.14 * true --> real"); + t.is(v20.get_real(), 3.14, EPSILON, "3.14 * true --> 3.14"); // real * integer -> real Variant v21 = v2 * v1; - t.is (v21.type (), Variant::type_real, "3.14 * 42 --> real"); - t.is (v21.get_real (), 131.88, EPSILON, "3.14 * 42 --> 131.88"); + t.is(v21.type(), Variant::type_real, "3.14 * 42 --> real"); + t.is(v21.get_real(), 131.88, EPSILON, "3.14 * 42 --> 131.88"); // real * real -> real Variant v22 = v2 * v2; - t.is (v22.type (), Variant::type_real, "3.14 * 3.14 --> real"); - t.is (v22.get_real (), 9.8596, EPSILON, "3.14 * 3.14 --> 9.8596"); + t.is(v22.type(), Variant::type_real, "3.14 * 3.14 --> real"); + t.is(v22.get_real(), 9.8596, EPSILON, "3.14 * 3.14 --> 9.8596"); // real * string -> error - try {Variant v23 = v2 * v3; t.fail ("3.14 * foo --> error");} - catch (...) {t.pass ("3.14 * foo --> error");} + try { + Variant v23 = v2 * v3; + t.fail("3.14 * foo --> error"); + } catch (...) { + t.pass("3.14 * foo --> error"); + } // real * date -> error - try {Variant v24 = v2 * v4; t.fail ("3.14 * 1234567890 --> error");} - catch (...) {t.pass ("3.14 * 1234567890 --> error");} + try { + Variant v24 = v2 * v4; + t.fail("3.14 * 1234567890 --> error"); + } catch (...) { + t.pass("3.14 * 1234567890 --> error"); + } // real * duration -> duration Variant v25 = v2 * v5; - t.is (v25.type (), Variant::type_duration, "3.14 * 1200 --> duration"); - t.is (v25.get_duration (), 3768, "3.14 * 1200 --> 3768"); + t.is(v25.type(), Variant::type_duration, "3.14 * 1200 --> duration"); + t.is(v25.get_duration(), 3768, "3.14 * 1200 --> 3768"); // string * boolean -> string Variant v30 = v3 * v0; - t.is (v30.type (), Variant::type_string, "foo * true --> real"); - t.is (v30.get_string (), "foo", "foo * true --> foo"); + t.is(v30.type(), Variant::type_string, "foo * true --> real"); + t.is(v30.get_string(), "foo", "foo * true --> foo"); // string * integer -> string Variant v31 = v3 * v1; - t.is (v31.type (), Variant::type_string, "foo * 42 --> string"); - t.is (v31.get_string ().substr (0, 10), "foofoofoof", - "foo * 42 --> foofoofoof..."); + t.is(v31.type(), Variant::type_string, "foo * 42 --> string"); + t.is(v31.get_string().substr(0, 10), "foofoofoof", "foo * 42 --> foofoofoof..."); // string * real -> string - try {Variant v32 = v3 * v2; t.fail ("foo * 3.14 --> error");} - catch (...) {t.pass ("foo * 3.14 --> error");} + try { + Variant v32 = v3 * v2; + t.fail("foo * 3.14 --> error"); + } catch (...) { + t.pass("foo * 3.14 --> error"); + } // string * string -> string - try {Variant v33 = v3 * v3; t.fail ("foo * foo --> error");} - catch (...) {t.pass ("foo * foo --> error");} + try { + Variant v33 = v3 * v3; + t.fail("foo * foo --> error"); + } catch (...) { + t.pass("foo * foo --> error"); + } // string * date -> string - try {Variant v34 = v3 * v4; t.fail ("foo * 1234567890 --> error");} - catch (...) {t.pass ("foo * 1234567890 --> error");} + try { + Variant v34 = v3 * v4; + t.fail("foo * 1234567890 --> error"); + } catch (...) { + t.pass("foo * 1234567890 --> error"); + } // string * duration -> string - try {Variant v35 = v3 * v5; t.fail ("foo * 1200 --> error");} - catch (...) {t.pass ("foo * 1200 --> error");} + try { + Variant v35 = v3 * v5; + t.fail("foo * 1200 --> error"); + } catch (...) { + t.pass("foo * 1200 --> error"); + } // date * boolean -> ERROR - try {Variant v40 = v4 * v0; t.fail ("1234567890 * true --> error");} - catch (...) {t.pass ("1234567890 * true --> error");} + try { + Variant v40 = v4 * v0; + t.fail("1234567890 * true --> error"); + } catch (...) { + t.pass("1234567890 * true --> error"); + } // date * integer -> ERROR - try {Variant v41 = v4 * v1; t.fail ("1234567890 * 42 --> error");} - catch (...) {t.pass ("1234567890 * 42 --> error");} + try { + Variant v41 = v4 * v1; + t.fail("1234567890 * 42 --> error"); + } catch (...) { + t.pass("1234567890 * 42 --> error"); + } // date * real -> ERROR - try {Variant v42 = v4 * v2; t.fail ("1234567890 * 3.14 --> error");} - catch (...) {t.pass ("1234567890 * 3.14 --> error");} + try { + Variant v42 = v4 * v2; + t.fail("1234567890 * 3.14 --> error"); + } catch (...) { + t.pass("1234567890 * 3.14 --> error"); + } // date * string -> ERROR - try {Variant v43 = v4 * v3; t.fail ("1234567890 * foo --> error");} - catch (...) {t.pass ("1234567890 * foo --> error");} + try { + Variant v43 = v4 * v3; + t.fail("1234567890 * foo --> error"); + } catch (...) { + t.pass("1234567890 * foo --> error"); + } // date * date -> ERROR - try {Variant v44 = v4 * v4; t.fail ("1234567890 * 1234567890 --> error");} - catch (...) {t.pass ("1234567890 * 1234567890 --> error");} + try { + Variant v44 = v4 * v4; + t.fail("1234567890 * 1234567890 --> error"); + } catch (...) { + t.pass("1234567890 * 1234567890 --> error"); + } // date * duration -> ERROR - try {Variant v45 = v4 * v5; t.fail ("1234567890 * 1200 --> error");} - catch (...) {t.pass ("1234567890 * 1200 --> error");} + try { + Variant v45 = v4 * v5; + t.fail("1234567890 * 1200 --> error"); + } catch (...) { + t.pass("1234567890 * 1200 --> error"); + } // duration * boolean -> duration Variant v50 = v5 * v0; - t.is (v50.type (), Variant::type_duration, "1200 * true --> duration"); - t.is (v50.get_duration (), 1200, "1200 * true --> 1200"); + t.is(v50.type(), Variant::type_duration, "1200 * true --> duration"); + t.is(v50.get_duration(), 1200, "1200 * true --> 1200"); // duration * integer -> duration Variant v51 = v5 * v1; - t.is (v51.type (), Variant::type_duration, "1200 * 42 --> duration"); - t.is (v51.get_duration (), 50400, "1200 * 42 --> 50400"); + t.is(v51.type(), Variant::type_duration, "1200 * 42 --> duration"); + t.is(v51.get_duration(), 50400, "1200 * 42 --> 50400"); // duration * real -> duration Variant v52 = v5 * v2; - t.is (v52.type (), Variant::type_duration, "1200 * 3.14 --> duration"); - t.is (v52.get_duration (), 3768, "1200 * 3.14 --> 3768"); + t.is(v52.type(), Variant::type_duration, "1200 * 3.14 --> duration"); + t.is(v52.get_duration(), 3768, "1200 * 3.14 --> 3768"); // duration * string -> string - try {Variant v53 = v5 * v3; t.fail ("1200 * foo --> error");} - catch (...) {t.pass ("1200 * foo --> error");} + try { + Variant v53 = v5 * v3; + t.fail("1200 * foo --> error"); + } catch (...) { + t.pass("1200 * foo --> error"); + } // duration * date -> date - try {Variant v54 = v5 * v4; t.fail ("1200 * 1234567890 --> error");} - catch (...) {t.pass ("1200 * 1234567890 --> error");} + try { + Variant v54 = v5 * v4; + t.fail("1200 * 1234567890 --> error"); + } catch (...) { + t.pass("1200 * 1234567890 --> error"); + } // duration * duration -> duration - try {Variant v55 = v5 * v5; t.fail ("1200 * 1200 --> error");} - catch (...) {t.pass ("1200 * 1200 --> error");} + try { + Variant v55 = v5 * v5; + t.fail("1200 * 1200 --> error"); + } catch (...) { + t.pass("1200 * 1200 --> error"); + } return 0; } diff --git a/test/variant_nomatch.test.cpp b/test/variant_nomatch.test.cpp index 0f069f9d9..827facb25 100644 --- a/test/variant_nomatch.test.cpp +++ b/test/variant_nomatch.test.cpp @@ -27,271 +27,271 @@ #include // cmake.h include header must come first -#include -#include -#include #include +#include +#include + +#include Task task; //////////////////////////////////////////////////////////////////////////////// -int main (int, char**) -{ - UnitTest t (120); +int main(int, char**) { + UnitTest t(120); - Variant vs0 ("untrue"); // !~ true - Variant vs1 (8421); // !~ 42 - Variant vs2 (3.14159); // !~ 3.14 - Variant vs3 ("foolish"); // !~ foo + Variant vs0("untrue"); // !~ true + Variant vs1(8421); // !~ 42 + Variant vs2(3.14159); // !~ 3.14 + Variant vs3("foolish"); // !~ foo - Variant v0 (true); - Variant v1 (42); - Variant v2 (3.14); - Variant v3 ("foo"); - Variant v4 (1234567890, Variant::type_date); - Variant v5 (1200, Variant::type_duration); + Variant v0(true); + Variant v1(42); + Variant v2(3.14); + Variant v3("foo"); + Variant v4(1234567890, Variant::type_date); + Variant v5(1200, Variant::type_duration); // Interesting cases. - Variant vs00 = vs0.operator_nomatch (v0, task); - t.is (vs00.type (), Variant::type_boolean, "untrue !~ true --> boolean"); - t.is (vs00.get_bool (), false, "untrue !~ true --> false"); + Variant vs00 = vs0.operator_nomatch(v0, task); + t.is(vs00.type(), Variant::type_boolean, "untrue !~ true --> boolean"); + t.is(vs00.get_bool(), false, "untrue !~ true --> false"); - Variant vs01 = vs0.operator_nomatch (v1, task); - t.is (vs01.type (), Variant::type_boolean, "untrue !~ 42 --> boolean"); - t.is (vs01.get_bool (), true, "untrue !~ 42 --> true"); + Variant vs01 = vs0.operator_nomatch(v1, task); + t.is(vs01.type(), Variant::type_boolean, "untrue !~ 42 --> boolean"); + t.is(vs01.get_bool(), true, "untrue !~ 42 --> true"); - Variant vs02 = vs0.operator_nomatch (v2, task); - t.is (vs02.type (), Variant::type_boolean, "untrue !~ 3.14 --> boolean"); - t.is (vs02.get_bool (), true, "untrue !~ 3.14 --> true"); + Variant vs02 = vs0.operator_nomatch(v2, task); + t.is(vs02.type(), Variant::type_boolean, "untrue !~ 3.14 --> boolean"); + t.is(vs02.get_bool(), true, "untrue !~ 3.14 --> true"); - Variant vs03 = vs0.operator_nomatch (v3, task); - t.is (vs03.type (), Variant::type_boolean, "untrue !~ 'foo' --> boolean"); - t.is (vs03.get_bool (), true, "untrue !~ 'foo' --> true"); + Variant vs03 = vs0.operator_nomatch(v3, task); + t.is(vs03.type(), Variant::type_boolean, "untrue !~ 'foo' --> boolean"); + t.is(vs03.get_bool(), true, "untrue !~ 'foo' --> true"); - Variant vs04 = vs0.operator_nomatch (v4, task); - t.is (vs04.type (), Variant::type_boolean, "untrue !~ 1234567890 --> boolean"); - t.is (vs04.get_bool (), true, "untrue !~ 1234567890 --> true"); + Variant vs04 = vs0.operator_nomatch(v4, task); + t.is(vs04.type(), Variant::type_boolean, "untrue !~ 1234567890 --> boolean"); + t.is(vs04.get_bool(), true, "untrue !~ 1234567890 --> true"); - Variant vs05 = vs0.operator_nomatch (v5, task); - t.is (vs05.type (), Variant::type_boolean, "untrue !~ 1200 --> boolean"); - t.is (vs05.get_bool (), true, "untrue !~ 1200 --> true"); + Variant vs05 = vs0.operator_nomatch(v5, task); + t.is(vs05.type(), Variant::type_boolean, "untrue !~ 1200 --> boolean"); + t.is(vs05.get_bool(), true, "untrue !~ 1200 --> true"); - Variant vs10 = vs1.operator_nomatch (v0, task); - t.is (vs10.type (), Variant::type_boolean, "8421 !~ true --> boolean"); - t.is (vs10.get_bool (), true, "8421 !~ true --> true"); + Variant vs10 = vs1.operator_nomatch(v0, task); + t.is(vs10.type(), Variant::type_boolean, "8421 !~ true --> boolean"); + t.is(vs10.get_bool(), true, "8421 !~ true --> true"); - Variant vs11 = vs1.operator_nomatch (v1, task); - t.is (vs11.type (), Variant::type_boolean, "8421 !~ 42 --> boolean"); - t.is (vs11.get_bool (), false, "8421 !~ 42 --> false"); + Variant vs11 = vs1.operator_nomatch(v1, task); + t.is(vs11.type(), Variant::type_boolean, "8421 !~ 42 --> boolean"); + t.is(vs11.get_bool(), false, "8421 !~ 42 --> false"); - Variant vs12 = vs1.operator_nomatch (v2, task); - t.is (vs12.type (), Variant::type_boolean, "8421 !~ 3.14 --> boolean"); - t.is (vs12.get_bool (), true, "8421 !~ 3.14 --> true"); + Variant vs12 = vs1.operator_nomatch(v2, task); + t.is(vs12.type(), Variant::type_boolean, "8421 !~ 3.14 --> boolean"); + t.is(vs12.get_bool(), true, "8421 !~ 3.14 --> true"); - Variant vs13 = vs1.operator_nomatch (v3, task); - t.is (vs13.type (), Variant::type_boolean, "8421 !~ 'foo' --> boolean"); - t.is (vs13.get_bool (), true, "8421 !~ 'foo' --> true"); + Variant vs13 = vs1.operator_nomatch(v3, task); + t.is(vs13.type(), Variant::type_boolean, "8421 !~ 'foo' --> boolean"); + t.is(vs13.get_bool(), true, "8421 !~ 'foo' --> true"); - Variant vs14 = vs1.operator_nomatch (v4, task); - t.is (vs14.type (), Variant::type_boolean, "8421 !~ 1234567890 --> boolean"); - t.is (vs14.get_bool (), true, "8421 !~ 1234567890 --> true"); + Variant vs14 = vs1.operator_nomatch(v4, task); + t.is(vs14.type(), Variant::type_boolean, "8421 !~ 1234567890 --> boolean"); + t.is(vs14.get_bool(), true, "8421 !~ 1234567890 --> true"); - Variant vs15 = vs1.operator_nomatch (v5, task); - t.is (vs15.type (), Variant::type_boolean, "8421 !~ 1200 --> boolean"); - t.is (vs15.get_bool (), true, "8421 !~ 1200 --> true"); + Variant vs15 = vs1.operator_nomatch(v5, task); + t.is(vs15.type(), Variant::type_boolean, "8421 !~ 1200 --> boolean"); + t.is(vs15.get_bool(), true, "8421 !~ 1200 --> true"); - Variant vs20 = vs2.operator_nomatch (v0, task); - t.is (vs20.type (), Variant::type_boolean, "3.14159 !~ true --> boolean"); - t.is (vs20.get_bool (), true, "3.14159 !~ true --> true"); + Variant vs20 = vs2.operator_nomatch(v0, task); + t.is(vs20.type(), Variant::type_boolean, "3.14159 !~ true --> boolean"); + t.is(vs20.get_bool(), true, "3.14159 !~ true --> true"); - Variant vs21 = vs2.operator_nomatch (v1, task); - t.is (vs21.type (), Variant::type_boolean, "3.14159 !~ 42 --> boolean"); - t.is (vs21.get_bool (), true, "3.14159 !~ 42 --> true"); + Variant vs21 = vs2.operator_nomatch(v1, task); + t.is(vs21.type(), Variant::type_boolean, "3.14159 !~ 42 --> boolean"); + t.is(vs21.get_bool(), true, "3.14159 !~ 42 --> true"); - Variant vs22 = vs2.operator_nomatch (v2, task); - t.is (vs22.type (), Variant::type_boolean, "3.14159 !~ 3.14 --> boolean"); - t.is (vs22.get_bool (), false, "3.14159 !~ 3.14 --> false"); + Variant vs22 = vs2.operator_nomatch(v2, task); + t.is(vs22.type(), Variant::type_boolean, "3.14159 !~ 3.14 --> boolean"); + t.is(vs22.get_bool(), false, "3.14159 !~ 3.14 --> false"); - Variant vs23 = vs2.operator_nomatch (v3, task); - t.is (vs23.type (), Variant::type_boolean, "3.14159 !~ 'foo' --> boolean"); - t.is (vs23.get_bool (), true, "3.14159 !~ 'foo' --> true"); + Variant vs23 = vs2.operator_nomatch(v3, task); + t.is(vs23.type(), Variant::type_boolean, "3.14159 !~ 'foo' --> boolean"); + t.is(vs23.get_bool(), true, "3.14159 !~ 'foo' --> true"); - Variant vs24 = vs2.operator_nomatch (v4, task); - t.is (vs24.type (), Variant::type_boolean, "3.14159 !~ 1234567890 --> boolean"); - t.is (vs24.get_bool (), true, "3.14159 !~ 1234567890 --> true"); + Variant vs24 = vs2.operator_nomatch(v4, task); + t.is(vs24.type(), Variant::type_boolean, "3.14159 !~ 1234567890 --> boolean"); + t.is(vs24.get_bool(), true, "3.14159 !~ 1234567890 --> true"); - Variant vs25 = vs2.operator_nomatch (v5, task); - t.is (vs25.type (), Variant::type_boolean, "3.14159 !~ 1200 --> boolean"); - t.is (vs25.get_bool (), true, "3.14159 !~ 1200 --> true"); + Variant vs25 = vs2.operator_nomatch(v5, task); + t.is(vs25.type(), Variant::type_boolean, "3.14159 !~ 1200 --> boolean"); + t.is(vs25.get_bool(), true, "3.14159 !~ 1200 --> true"); - Variant vs30 = vs3.operator_nomatch (v0, task); - t.is (vs30.type (), Variant::type_boolean, "foolish !~ true --> boolean"); - t.is (vs30.get_bool (), true, "foolish !~ true --> true"); + Variant vs30 = vs3.operator_nomatch(v0, task); + t.is(vs30.type(), Variant::type_boolean, "foolish !~ true --> boolean"); + t.is(vs30.get_bool(), true, "foolish !~ true --> true"); - Variant vs31 = vs3.operator_nomatch (v1, task); - t.is (vs31.type (), Variant::type_boolean, "foolish !~ 42 --> boolean"); - t.is (vs31.get_bool (), true, "foolish !~ 42 --> true"); + Variant vs31 = vs3.operator_nomatch(v1, task); + t.is(vs31.type(), Variant::type_boolean, "foolish !~ 42 --> boolean"); + t.is(vs31.get_bool(), true, "foolish !~ 42 --> true"); - Variant vs32 = vs3.operator_nomatch (v2, task); - t.is (vs32.type (), Variant::type_boolean, "foolish !~ 3.14 --> boolean"); - t.is (vs32.get_bool (), true, "foolish !~ 3.14 --> true"); + Variant vs32 = vs3.operator_nomatch(v2, task); + t.is(vs32.type(), Variant::type_boolean, "foolish !~ 3.14 --> boolean"); + t.is(vs32.get_bool(), true, "foolish !~ 3.14 --> true"); - Variant vs33 = vs3.operator_nomatch (v3, task); - t.is (vs33.type (), Variant::type_boolean, "foolish !~ 'foo' --> boolean"); - t.is (vs33.get_bool (), false, "foolish !~ 'foo' --> false"); + Variant vs33 = vs3.operator_nomatch(v3, task); + t.is(vs33.type(), Variant::type_boolean, "foolish !~ 'foo' --> boolean"); + t.is(vs33.get_bool(), false, "foolish !~ 'foo' --> false"); - Variant vs34 = vs3.operator_nomatch (v4, task); - t.is (vs34.type (), Variant::type_boolean, "foolish !~ 1234567890 --> boolean"); - t.is (vs34.get_bool (), true, "foolish !~ 1234567890 --> true"); + Variant vs34 = vs3.operator_nomatch(v4, task); + t.is(vs34.type(), Variant::type_boolean, "foolish !~ 1234567890 --> boolean"); + t.is(vs34.get_bool(), true, "foolish !~ 1234567890 --> true"); - Variant vs35 = vs3.operator_nomatch (v5, task); - t.is (vs35.type (), Variant::type_boolean, "foolish !~ 1200 --> boolean"); - t.is (vs35.get_bool (), true, "foolish !~ 1200 --> true"); + Variant vs35 = vs3.operator_nomatch(v5, task); + t.is(vs35.type(), Variant::type_boolean, "foolish !~ 1200 --> boolean"); + t.is(vs35.get_bool(), true, "foolish !~ 1200 --> true"); // Exhaustive comparisons. - Variant v00 = v0.operator_nomatch (v0, task); - t.is (v00.type (), Variant::type_boolean, "true !~ true --> boolean"); - t.is (v00.get_bool (), false, "true !~ true --> false"); + Variant v00 = v0.operator_nomatch(v0, task); + t.is(v00.type(), Variant::type_boolean, "true !~ true --> boolean"); + t.is(v00.get_bool(), false, "true !~ true --> false"); - Variant v01 = v0.operator_nomatch (v1, task); - t.is (v01.type (), Variant::type_boolean, "true !~ 42 --> boolean"); - t.is (v01.get_bool (), true, "true !~ 42 --> true"); + Variant v01 = v0.operator_nomatch(v1, task); + t.is(v01.type(), Variant::type_boolean, "true !~ 42 --> boolean"); + t.is(v01.get_bool(), true, "true !~ 42 --> true"); - Variant v02 = v0.operator_nomatch (v2, task); - t.is (v02.type (), Variant::type_boolean, "true !~ 3.14 --> boolean"); - t.is (v02.get_bool (), true, "true !~ 3.14 --> true"); + Variant v02 = v0.operator_nomatch(v2, task); + t.is(v02.type(), Variant::type_boolean, "true !~ 3.14 --> boolean"); + t.is(v02.get_bool(), true, "true !~ 3.14 --> true"); - Variant v03 = v0.operator_nomatch (v3, task); - t.is (v03.type (), Variant::type_boolean, "true !~ 'foo' --> boolean"); - t.is (v03.get_bool (), true, "true !~ 'foo' --> true"); + Variant v03 = v0.operator_nomatch(v3, task); + t.is(v03.type(), Variant::type_boolean, "true !~ 'foo' --> boolean"); + t.is(v03.get_bool(), true, "true !~ 'foo' --> true"); - Variant v04 = v0.operator_nomatch (v4, task); - t.is (v04.type (), Variant::type_boolean, "true !~ 1234567890 --> boolean"); - t.is (v04.get_bool (), true, "true !~ 1234567890 --> true"); + Variant v04 = v0.operator_nomatch(v4, task); + t.is(v04.type(), Variant::type_boolean, "true !~ 1234567890 --> boolean"); + t.is(v04.get_bool(), true, "true !~ 1234567890 --> true"); - Variant v05 = v0.operator_nomatch (v5, task); - t.is (v05.type (), Variant::type_boolean, "true !~ 1200 --> boolean"); - t.is (v05.get_bool (), true, "true !~ 1200 --> true"); + Variant v05 = v0.operator_nomatch(v5, task); + t.is(v05.type(), Variant::type_boolean, "true !~ 1200 --> boolean"); + t.is(v05.get_bool(), true, "true !~ 1200 --> true"); - Variant v10 = v1.operator_nomatch (v0, task); - t.is (v10.type (), Variant::type_boolean, "42 !~ true --> boolean"); - t.is (v10.get_bool (), true, "42 !~ true --> true"); + Variant v10 = v1.operator_nomatch(v0, task); + t.is(v10.type(), Variant::type_boolean, "42 !~ true --> boolean"); + t.is(v10.get_bool(), true, "42 !~ true --> true"); - Variant v11 = v1.operator_nomatch (v1, task); - t.is (v11.type (), Variant::type_boolean, "42 !~ 42 --> boolean"); - t.is (v11.get_bool (), false, "42 !~ 42 --> false"); + Variant v11 = v1.operator_nomatch(v1, task); + t.is(v11.type(), Variant::type_boolean, "42 !~ 42 --> boolean"); + t.is(v11.get_bool(), false, "42 !~ 42 --> false"); - Variant v12 = v1.operator_nomatch (v2, task); - t.is (v12.type (), Variant::type_boolean, "42 !~ 3.14 --> boolean"); - t.is (v12.get_bool (), true, "42 !~ 3.14 --> true"); + Variant v12 = v1.operator_nomatch(v2, task); + t.is(v12.type(), Variant::type_boolean, "42 !~ 3.14 --> boolean"); + t.is(v12.get_bool(), true, "42 !~ 3.14 --> true"); - Variant v13 = v1.operator_nomatch (v3, task); - t.is (v13.type (), Variant::type_boolean, "42 !~ 'foo' --> boolean"); - t.is (v13.get_bool (), true, "42 !~ 'foo' --> true"); + Variant v13 = v1.operator_nomatch(v3, task); + t.is(v13.type(), Variant::type_boolean, "42 !~ 'foo' --> boolean"); + t.is(v13.get_bool(), true, "42 !~ 'foo' --> true"); - Variant v14 = v1.operator_nomatch (v4, task); - t.is (v04.type (), Variant::type_boolean, "42 !~ 1234567890 --> boolean"); - t.is (v04.get_bool (), true, "42 !~ 1234567890 --> true"); + Variant v14 = v1.operator_nomatch(v4, task); + t.is(v04.type(), Variant::type_boolean, "42 !~ 1234567890 --> boolean"); + t.is(v04.get_bool(), true, "42 !~ 1234567890 --> true"); - Variant v15 = v1.operator_nomatch (v5, task); - t.is (v15.type (), Variant::type_boolean, "42 !~ 1200 --> boolean"); - t.is (v15.get_bool (), true, "42 !~ 1200 --> true"); + Variant v15 = v1.operator_nomatch(v5, task); + t.is(v15.type(), Variant::type_boolean, "42 !~ 1200 --> boolean"); + t.is(v15.get_bool(), true, "42 !~ 1200 --> true"); - Variant v20 = v2.operator_nomatch (v0, task); - t.is (v20.type (), Variant::type_boolean, "3.14 !~ true --> boolean"); - t.is (v20.get_bool (), true, "3.14 !~ true --> true"); + Variant v20 = v2.operator_nomatch(v0, task); + t.is(v20.type(), Variant::type_boolean, "3.14 !~ true --> boolean"); + t.is(v20.get_bool(), true, "3.14 !~ true --> true"); - Variant v21 = v2.operator_nomatch (v1, task); - t.is (v21.type (), Variant::type_boolean, "3.14 !~ 42 --> boolean"); - t.is (v21.get_bool (), true, "3.14 !~ 42 --> true"); + Variant v21 = v2.operator_nomatch(v1, task); + t.is(v21.type(), Variant::type_boolean, "3.14 !~ 42 --> boolean"); + t.is(v21.get_bool(), true, "3.14 !~ 42 --> true"); - Variant v22 = v2.operator_nomatch (v2, task); - t.is (v22.type (), Variant::type_boolean, "3.14 !~ 3.14 --> boolean"); - t.is (v22.get_bool (), false, "3.14 !~ 3.14 --> false"); + Variant v22 = v2.operator_nomatch(v2, task); + t.is(v22.type(), Variant::type_boolean, "3.14 !~ 3.14 --> boolean"); + t.is(v22.get_bool(), false, "3.14 !~ 3.14 --> false"); - Variant v23 = v2.operator_nomatch (v3, task); - t.is (v23.type (), Variant::type_boolean, "3.14 !~ 'foo' --> boolean"); - t.is (v23.get_bool (), true, "3.14 !~ 'foo' --> true"); + Variant v23 = v2.operator_nomatch(v3, task); + t.is(v23.type(), Variant::type_boolean, "3.14 !~ 'foo' --> boolean"); + t.is(v23.get_bool(), true, "3.14 !~ 'foo' --> true"); - Variant v24 = v2.operator_nomatch (v4, task); - t.is (v24.type (), Variant::type_boolean, "3.14 !~ 1234567890 --> boolean"); - t.is (v24.get_bool (), true, "3.14 !~ 1234567890 --> true"); + Variant v24 = v2.operator_nomatch(v4, task); + t.is(v24.type(), Variant::type_boolean, "3.14 !~ 1234567890 --> boolean"); + t.is(v24.get_bool(), true, "3.14 !~ 1234567890 --> true"); - Variant v25 = v2.operator_nomatch (v5, task); - t.is (v25.type (), Variant::type_boolean, "3.14 !~ 1200 --> boolean"); - t.is (v25.get_bool (), true, "3.14 !~ 1200 --> true"); + Variant v25 = v2.operator_nomatch(v5, task); + t.is(v25.type(), Variant::type_boolean, "3.14 !~ 1200 --> boolean"); + t.is(v25.get_bool(), true, "3.14 !~ 1200 --> true"); - Variant v30 = v3.operator_nomatch (v0, task); - t.is (v30.type (), Variant::type_boolean, "'foo' !~ true --> boolean"); - t.is (v30.get_bool (), true, "'foo' !~ true --> true"); + Variant v30 = v3.operator_nomatch(v0, task); + t.is(v30.type(), Variant::type_boolean, "'foo' !~ true --> boolean"); + t.is(v30.get_bool(), true, "'foo' !~ true --> true"); - Variant v31 = v3.operator_nomatch (v1, task); - t.is (v31.type (), Variant::type_boolean, "'foo' !~ 42 --> boolean"); - t.is (v31.get_bool (), true, "'foo' !~ 42 --> true"); + Variant v31 = v3.operator_nomatch(v1, task); + t.is(v31.type(), Variant::type_boolean, "'foo' !~ 42 --> boolean"); + t.is(v31.get_bool(), true, "'foo' !~ 42 --> true"); - Variant v32 = v3.operator_nomatch (v2, task); - t.is (v32.type (), Variant::type_boolean, "'foo' !~ 3.14 --> boolean"); - t.is (v32.get_bool (), true, "'foo' !~ 3.14 --> true"); + Variant v32 = v3.operator_nomatch(v2, task); + t.is(v32.type(), Variant::type_boolean, "'foo' !~ 3.14 --> boolean"); + t.is(v32.get_bool(), true, "'foo' !~ 3.14 --> true"); - Variant v33 = v3.operator_nomatch (v3, task); - t.is (v33.type (), Variant::type_boolean, "'foo' !~ 'foo' --> boolean"); - t.is (v33.get_bool (), false, "'foo' !~ 'foo' --> false"); + Variant v33 = v3.operator_nomatch(v3, task); + t.is(v33.type(), Variant::type_boolean, "'foo' !~ 'foo' --> boolean"); + t.is(v33.get_bool(), false, "'foo' !~ 'foo' --> false"); - Variant v34 = v3.operator_nomatch (v4, task); - t.is (v34.type (), Variant::type_boolean, "'foo' !~ 1234567890 --> boolean"); - t.is (v34.get_bool (), true, "'foo' !~ 1234567890 --> true"); + Variant v34 = v3.operator_nomatch(v4, task); + t.is(v34.type(), Variant::type_boolean, "'foo' !~ 1234567890 --> boolean"); + t.is(v34.get_bool(), true, "'foo' !~ 1234567890 --> true"); - Variant v35 = v3.operator_nomatch (v5, task); - t.is (v35.type (), Variant::type_boolean, "'foo' !~ 1200 --> boolean"); - t.is (v35.get_bool (), true, "'foo' !~ 1200 --> true"); + Variant v35 = v3.operator_nomatch(v5, task); + t.is(v35.type(), Variant::type_boolean, "'foo' !~ 1200 --> boolean"); + t.is(v35.get_bool(), true, "'foo' !~ 1200 --> true"); - Variant v40 = v4.operator_nomatch (v0, task); - t.is (v40.type (), Variant::type_boolean, "1234567890 !~ true --> boolean"); - t.is (v40.get_bool (), true, "1234567890 !~ true --> true"); + Variant v40 = v4.operator_nomatch(v0, task); + t.is(v40.type(), Variant::type_boolean, "1234567890 !~ true --> boolean"); + t.is(v40.get_bool(), true, "1234567890 !~ true --> true"); - Variant v41 = v4.operator_nomatch (v1, task); - t.is (v41.type (), Variant::type_boolean, "1234567890 !~ 42 --> boolean"); - t.is (v41.get_bool (), true, "1234567890 !~ 42 --> true"); + Variant v41 = v4.operator_nomatch(v1, task); + t.is(v41.type(), Variant::type_boolean, "1234567890 !~ 42 --> boolean"); + t.is(v41.get_bool(), true, "1234567890 !~ 42 --> true"); - Variant v42 = v4.operator_nomatch (v2, task); - t.is (v42.type (), Variant::type_boolean, "1234567890 !~ 3.14 --> boolean"); - t.is (v42.get_bool (), true, "1234567890 !~ 3.14 --> true"); + Variant v42 = v4.operator_nomatch(v2, task); + t.is(v42.type(), Variant::type_boolean, "1234567890 !~ 3.14 --> boolean"); + t.is(v42.get_bool(), true, "1234567890 !~ 3.14 --> true"); - Variant v43 = v4.operator_nomatch (v3, task); - t.is (v43.type (), Variant::type_boolean, "1234567890 !~ 'foo' --> boolean"); - t.is (v43.get_bool (), true, "1234567890 !~ 'foo' --> true"); + Variant v43 = v4.operator_nomatch(v3, task); + t.is(v43.type(), Variant::type_boolean, "1234567890 !~ 'foo' --> boolean"); + t.is(v43.get_bool(), true, "1234567890 !~ 'foo' --> true"); - Variant v44 = v4.operator_nomatch (v4, task); - t.is (v44.type (), Variant::type_boolean, "1234567890 !~ 1234567890 --> boolean"); - t.is (v44.get_bool (), false, "1234567890 !~ 1234567890 --> false"); + Variant v44 = v4.operator_nomatch(v4, task); + t.is(v44.type(), Variant::type_boolean, "1234567890 !~ 1234567890 --> boolean"); + t.is(v44.get_bool(), false, "1234567890 !~ 1234567890 --> false"); - Variant v45 = v4.operator_nomatch (v5, task); - t.is (v45.type (), Variant::type_boolean, "1234567890 !~ 1200 --> boolean"); - t.is (v45.get_bool (), true, "1234567890 !~ 1200 --> true"); + Variant v45 = v4.operator_nomatch(v5, task); + t.is(v45.type(), Variant::type_boolean, "1234567890 !~ 1200 --> boolean"); + t.is(v45.get_bool(), true, "1234567890 !~ 1200 --> true"); - Variant v50 = v5.operator_nomatch (v0, task); - t.is (v50.type (), Variant::type_boolean, "1200 !~ true --> boolean"); - t.is (v50.get_bool (), true, "1200 !~ true --> true"); + Variant v50 = v5.operator_nomatch(v0, task); + t.is(v50.type(), Variant::type_boolean, "1200 !~ true --> boolean"); + t.is(v50.get_bool(), true, "1200 !~ true --> true"); - Variant v51 = v5.operator_nomatch (v1, task); - t.is (v51.type (), Variant::type_boolean, "1200 !~ 42 --> boolean"); - t.is (v51.get_bool (), true, "1200 !~ 42 --> true"); + Variant v51 = v5.operator_nomatch(v1, task); + t.is(v51.type(), Variant::type_boolean, "1200 !~ 42 --> boolean"); + t.is(v51.get_bool(), true, "1200 !~ 42 --> true"); - Variant v52 = v5.operator_nomatch (v2, task); - t.is (v52.type (), Variant::type_boolean, "1200 !~ 3.14 --> boolean"); - t.is (v52.get_bool (), true, "1200 !~ 3.14 --> true"); + Variant v52 = v5.operator_nomatch(v2, task); + t.is(v52.type(), Variant::type_boolean, "1200 !~ 3.14 --> boolean"); + t.is(v52.get_bool(), true, "1200 !~ 3.14 --> true"); - Variant v53 = v5.operator_nomatch (v3, task); - t.is (v53.type (), Variant::type_boolean, "1200 !~ 'foo' --> boolean"); - t.is (v53.get_bool (), true, "1200 !~ 'foo' --> true"); + Variant v53 = v5.operator_nomatch(v3, task); + t.is(v53.type(), Variant::type_boolean, "1200 !~ 'foo' --> boolean"); + t.is(v53.get_bool(), true, "1200 !~ 'foo' --> true"); - Variant v54 = v5.operator_nomatch (v4, task); - t.is (v04.type (), Variant::type_boolean, "1200 !~ 1234567890 --> boolean"); - t.is (v04.get_bool (), true, "1200 !~ 1234567890 --> true"); + Variant v54 = v5.operator_nomatch(v4, task); + t.is(v04.type(), Variant::type_boolean, "1200 !~ 1234567890 --> boolean"); + t.is(v04.get_bool(), true, "1200 !~ 1234567890 --> true"); - Variant v55 = v5.operator_nomatch (v5, task); - t.is (v55.type (), Variant::type_boolean, "1200 !~ 1200 --> boolean"); - t.is (v55.get_bool (), false, "1200 !~ 1200 --> false"); + Variant v55 = v5.operator_nomatch(v5, task); + t.is(v55.type(), Variant::type_boolean, "1200 !~ 1200 --> boolean"); + t.is(v55.get_bool(), false, "1200 !~ 1200 --> false"); return 0; } diff --git a/test/variant_not.test.cpp b/test/variant_not.test.cpp index aad898cc3..cafc4aa5c 100644 --- a/test/variant_not.test.cpp +++ b/test/variant_not.test.cpp @@ -27,51 +27,51 @@ #include // cmake.h include header must come first -#include -#include #include +#include + +#include //////////////////////////////////////////////////////////////////////////////// -int main (int, char**) -{ - UnitTest t (14); +int main(int, char**) { + UnitTest t(14); - Variant v0 (true); - Variant v1 (42); - Variant v2 (3.14); - Variant v3 ("foo"); - Variant v4 (1234567890, Variant::type_date); - Variant v5 (1200, Variant::type_duration); + Variant v0(true); + Variant v1(42); + Variant v2(3.14); + Variant v3("foo"); + Variant v4(1234567890, Variant::type_date); + Variant v5(1200, Variant::type_duration); // Truth table. - Variant vFalse (false); - Variant vTrue (true); - t.is (!vFalse, true, "!false --> true"); - t.is (!vTrue, false, "!true --> false"); + Variant vFalse(false); + Variant vTrue(true); + t.is(!vFalse, true, "!false --> true"); + t.is(!vTrue, false, "!true --> false"); - Variant v00 = ! v0; - t.is (v00.type (), Variant::type_boolean, "! true --> boolean"); - t.is (v00.get_bool (), false, "! true --> false"); + Variant v00 = !v0; + t.is(v00.type(), Variant::type_boolean, "! true --> boolean"); + t.is(v00.get_bool(), false, "! true --> false"); - Variant v01 = ! v1; - t.is (v01.type (), Variant::type_boolean, "! 42 --> boolean"); - t.is (v01.get_bool (), false, "! 42 --> false"); + Variant v01 = !v1; + t.is(v01.type(), Variant::type_boolean, "! 42 --> boolean"); + t.is(v01.get_bool(), false, "! 42 --> false"); - Variant v02 = ! v2; - t.is (v02.type (), Variant::type_boolean, "! 3.14 --> boolean"); - t.is (v02.get_bool (), false, "! 3.14 --> false"); + Variant v02 = !v2; + t.is(v02.type(), Variant::type_boolean, "! 3.14 --> boolean"); + t.is(v02.get_bool(), false, "! 3.14 --> false"); - Variant v03 = ! v3; - t.is (v03.type (), Variant::type_boolean, "! foo --> boolean"); - t.is (v03.get_bool (), false, "! foo --> false"); + Variant v03 = !v3; + t.is(v03.type(), Variant::type_boolean, "! foo --> boolean"); + t.is(v03.get_bool(), false, "! foo --> false"); - Variant v04 = ! v4; - t.is (v04.type (), Variant::type_boolean, "! 1234567890 --> boolean"); - t.is (v04.get_bool (), false, "! 1234567890 --> false"); + Variant v04 = !v4; + t.is(v04.type(), Variant::type_boolean, "! 1234567890 --> boolean"); + t.is(v04.get_bool(), false, "! 1234567890 --> false"); - Variant v05 = ! v5; - t.is (v05.type (), Variant::type_boolean, "! 1200 --> boolean"); - t.is (v05.get_bool (), false, "! 1200 --> false"); + Variant v05 = !v5; + t.is(v05.type(), Variant::type_boolean, "! 1200 --> boolean"); + t.is(v05.get_bool(), false, "! 1200 --> false"); return 0; } diff --git a/test/variant_or.test.cpp b/test/variant_or.test.cpp index 010406d7f..056e47a8e 100644 --- a/test/variant_or.test.cpp +++ b/test/variant_or.test.cpp @@ -27,173 +27,173 @@ #include // cmake.h include header must come first -#include -#include #include +#include + +#include //////////////////////////////////////////////////////////////////////////////// -int main (int, char**) -{ - UnitTest t (76); +int main(int, char**) { + UnitTest t(76); - Variant v0 (true); - Variant v1 (42); - Variant v2 (3.14); - Variant v3 ("foo"); - Variant v4 (1234567890, Variant::type_date); - Variant v5 (1200, Variant::type_duration); + Variant v0(true); + Variant v1(42); + Variant v2(3.14); + Variant v3("foo"); + Variant v4(1234567890, Variant::type_date); + Variant v5(1200, Variant::type_duration); // Truth table. - Variant vFalse (false); - Variant vTrue (true); - t.is (vFalse || vFalse, false, "false || false --> false"); - t.is (vFalse || vTrue, true, "false || true --> true"); - t.is (vTrue || vFalse, true, "true || false --> true"); - t.is (vTrue || vTrue, true, "true || true --> true"); + Variant vFalse(false); + Variant vTrue(true); + t.is(vFalse || vFalse, false, "false || false --> false"); + t.is(vFalse || vTrue, true, "false || true --> true"); + t.is(vTrue || vFalse, true, "true || false --> true"); + t.is(vTrue || vTrue, true, "true || true --> true"); Variant v00 = v0 || v0; - t.is (v00.type (), Variant::type_boolean, "true || true --> boolean"); - t.is (v00.get_bool (), true, "true || true --> true"); + t.is(v00.type(), Variant::type_boolean, "true || true --> boolean"); + t.is(v00.get_bool(), true, "true || true --> true"); Variant v01 = v0 || v1; - t.is (v01.type (), Variant::type_boolean, "true || 42 --> boolean"); - t.is (v01.get_bool (), true, "true || 42 --> true"); + t.is(v01.type(), Variant::type_boolean, "true || 42 --> boolean"); + t.is(v01.get_bool(), true, "true || 42 --> true"); Variant v02 = v0 || v2; - t.is (v02.type (), Variant::type_boolean, "true || 3.14 --> boolean"); - t.is (v02.get_bool (), true, "true || 3.14 --> true"); + t.is(v02.type(), Variant::type_boolean, "true || 3.14 --> boolean"); + t.is(v02.get_bool(), true, "true || 3.14 --> true"); Variant v03 = v0 || v3; - t.is (v03.type (), Variant::type_boolean, "true || 'foo' --> boolean"); - t.is (v03.get_bool (), true, "true || 'foo' --> true"); + t.is(v03.type(), Variant::type_boolean, "true || 'foo' --> boolean"); + t.is(v03.get_bool(), true, "true || 'foo' --> true"); Variant v04 = v0 || v4; - t.is (v04.type (), Variant::type_boolean, "true || 1234567890 --> boolean"); - t.is (v04.get_bool (), true, "true || 1234567890 --> true"); + t.is(v04.type(), Variant::type_boolean, "true || 1234567890 --> boolean"); + t.is(v04.get_bool(), true, "true || 1234567890 --> true"); Variant v05 = v0 || v5; - t.is (v05.type (), Variant::type_boolean, "true || 1200 --> boolean"); - t.is (v05.get_bool (), true, "true || 1200 --> true"); + t.is(v05.type(), Variant::type_boolean, "true || 1200 --> boolean"); + t.is(v05.get_bool(), true, "true || 1200 --> true"); Variant v10 = v1 || v0; - t.is (v10.type (), Variant::type_boolean, "42 || true --> boolean"); - t.is (v10.get_bool (), true, "42 || true --> true"); + t.is(v10.type(), Variant::type_boolean, "42 || true --> boolean"); + t.is(v10.get_bool(), true, "42 || true --> true"); Variant v11 = v1 || v1; - t.is (v11.type (), Variant::type_boolean, "42 || 42 --> boolean"); - t.is (v11.get_bool (), true, "42 || 42 --> true"); + t.is(v11.type(), Variant::type_boolean, "42 || 42 --> boolean"); + t.is(v11.get_bool(), true, "42 || 42 --> true"); Variant v12 = v1 || v2; - t.is (v12.type (), Variant::type_boolean, "42 || 3.14 --> boolean"); - t.is (v12.get_bool (), true, "42 || 3.14 --> true"); + t.is(v12.type(), Variant::type_boolean, "42 || 3.14 --> boolean"); + t.is(v12.get_bool(), true, "42 || 3.14 --> true"); Variant v13 = v1 || v3; - t.is (v13.type (), Variant::type_boolean, "42 || 'foo' --> boolean"); - t.is (v13.get_bool (), true, "42 || 'foo' --> true"); + t.is(v13.type(), Variant::type_boolean, "42 || 'foo' --> boolean"); + t.is(v13.get_bool(), true, "42 || 'foo' --> true"); Variant v14 = v1 || v4; - t.is (v04.type (), Variant::type_boolean, "42 || 1234567890 --> boolean"); - t.is (v04.get_bool (), true, "42 || 1234567890 --> true"); + t.is(v04.type(), Variant::type_boolean, "42 || 1234567890 --> boolean"); + t.is(v04.get_bool(), true, "42 || 1234567890 --> true"); Variant v15 = v1 || v5; - t.is (v15.type (), Variant::type_boolean, "42 || 1200 --> boolean"); - t.is (v15.get_bool (), true, "42 || 1200 --> true"); + t.is(v15.type(), Variant::type_boolean, "42 || 1200 --> boolean"); + t.is(v15.get_bool(), true, "42 || 1200 --> true"); Variant v20 = v2 || v0; - t.is (v20.type (), Variant::type_boolean, "3.14 || true --> boolean"); - t.is (v20.get_bool (), true, "3.14 || true --> true"); + t.is(v20.type(), Variant::type_boolean, "3.14 || true --> boolean"); + t.is(v20.get_bool(), true, "3.14 || true --> true"); Variant v21 = v2 || v1; - t.is (v21.type (), Variant::type_boolean, "3.14 || 42 --> boolean"); - t.is (v21.get_bool (), true, "3.14 || 42 --> true"); + t.is(v21.type(), Variant::type_boolean, "3.14 || 42 --> boolean"); + t.is(v21.get_bool(), true, "3.14 || 42 --> true"); Variant v22 = v2 || v2; - t.is (v22.type (), Variant::type_boolean, "3.14 || 3.14 --> boolean"); - t.is (v22.get_bool (), true, "3.14 || 3.14 --> true"); + t.is(v22.type(), Variant::type_boolean, "3.14 || 3.14 --> boolean"); + t.is(v22.get_bool(), true, "3.14 || 3.14 --> true"); Variant v23 = v2 || v3; - t.is (v23.type (), Variant::type_boolean, "3.14 || 'foo' --> boolean"); - t.is (v23.get_bool (), true, "3.14 || 'foo' --> true"); + t.is(v23.type(), Variant::type_boolean, "3.14 || 'foo' --> boolean"); + t.is(v23.get_bool(), true, "3.14 || 'foo' --> true"); Variant v24 = v2 || v4; - t.is (v24.type (), Variant::type_boolean, "3.14 || 1234567890 --> boolean"); - t.is (v24.get_bool (), true, "3.14 || 1234567890 --> true"); + t.is(v24.type(), Variant::type_boolean, "3.14 || 1234567890 --> boolean"); + t.is(v24.get_bool(), true, "3.14 || 1234567890 --> true"); Variant v25 = v2 || v5; - t.is (v25.type (), Variant::type_boolean, "3.14 || 1200 --> boolean"); - t.is (v25.get_bool (), true, "3.14 || 1200 --> true"); + t.is(v25.type(), Variant::type_boolean, "3.14 || 1200 --> boolean"); + t.is(v25.get_bool(), true, "3.14 || 1200 --> true"); Variant v30 = v3 || v0; - t.is (v30.type (), Variant::type_boolean, "'foo' || true --> boolean"); - t.is (v30.get_bool (), true, "'foo' || true --> true"); + t.is(v30.type(), Variant::type_boolean, "'foo' || true --> boolean"); + t.is(v30.get_bool(), true, "'foo' || true --> true"); Variant v31 = v3 || v1; - t.is (v31.type (), Variant::type_boolean, "'foo' || 42 --> boolean"); - t.is (v31.get_bool (), true, "'foo' || 42 --> true"); + t.is(v31.type(), Variant::type_boolean, "'foo' || 42 --> boolean"); + t.is(v31.get_bool(), true, "'foo' || 42 --> true"); Variant v32 = v3 || v2; - t.is (v32.type (), Variant::type_boolean, "'foo' || 3.14 --> boolean"); - t.is (v32.get_bool (), true, "'foo' || 3.14 --> true"); + t.is(v32.type(), Variant::type_boolean, "'foo' || 3.14 --> boolean"); + t.is(v32.get_bool(), true, "'foo' || 3.14 --> true"); Variant v33 = v3 || v3; - t.is (v33.type (), Variant::type_boolean, "'foo' || 'foo' --> boolean"); - t.is (v33.get_bool (), true, "'foo' || 'foo' --> true"); + t.is(v33.type(), Variant::type_boolean, "'foo' || 'foo' --> boolean"); + t.is(v33.get_bool(), true, "'foo' || 'foo' --> true"); Variant v34 = v3 || v4; - t.is (v34.type (), Variant::type_boolean, "'foo' || 1234567890 --> boolean"); - t.is (v34.get_bool (), true, "'foo' || 1234567890 --> true"); + t.is(v34.type(), Variant::type_boolean, "'foo' || 1234567890 --> boolean"); + t.is(v34.get_bool(), true, "'foo' || 1234567890 --> true"); Variant v35 = v3 || v5; - t.is (v35.type (), Variant::type_boolean, "'foo' || 1200 --> boolean"); - t.is (v35.get_bool (), true, "'foo' || 1200 --> true"); + t.is(v35.type(), Variant::type_boolean, "'foo' || 1200 --> boolean"); + t.is(v35.get_bool(), true, "'foo' || 1200 --> true"); Variant v40 = v4 || v0; - t.is (v40.type (), Variant::type_boolean, "1234567890 || true --> boolean"); - t.is (v40.get_bool (), true, "1234567890 || true --> true"); + t.is(v40.type(), Variant::type_boolean, "1234567890 || true --> boolean"); + t.is(v40.get_bool(), true, "1234567890 || true --> true"); Variant v41 = v4 || v1; - t.is (v41.type (), Variant::type_boolean, "1234567890 || 42 --> boolean"); - t.is (v41.get_bool (), true, "1234567890 || 42 --> true"); + t.is(v41.type(), Variant::type_boolean, "1234567890 || 42 --> boolean"); + t.is(v41.get_bool(), true, "1234567890 || 42 --> true"); Variant v42 = v4 || v2; - t.is (v42.type (), Variant::type_boolean, "1234567890 || 3.14 --> boolean"); - t.is (v42.get_bool (), true, "1234567890 || 3.14 --> true"); + t.is(v42.type(), Variant::type_boolean, "1234567890 || 3.14 --> boolean"); + t.is(v42.get_bool(), true, "1234567890 || 3.14 --> true"); Variant v43 = v4 || v3; - t.is (v43.type (), Variant::type_boolean, "1234567890 || 'foo' --> boolean"); - t.is (v43.get_bool (), true, "1234567890 || 'foo' --> true"); + t.is(v43.type(), Variant::type_boolean, "1234567890 || 'foo' --> boolean"); + t.is(v43.get_bool(), true, "1234567890 || 'foo' --> true"); Variant v44 = v4 || v4; - t.is (v44.type (), Variant::type_boolean, "1234567890 || 1234567890 --> boolean"); - t.is (v44.get_bool (), true, "1234567890 || 1234567890 --> true"); + t.is(v44.type(), Variant::type_boolean, "1234567890 || 1234567890 --> boolean"); + t.is(v44.get_bool(), true, "1234567890 || 1234567890 --> true"); Variant v45 = v4 || v5; - t.is (v45.type (), Variant::type_boolean, "1234567890 || 1200 --> boolean"); - t.is (v45.get_bool (), true, "1234567890 || 1200 --> true"); + t.is(v45.type(), Variant::type_boolean, "1234567890 || 1200 --> boolean"); + t.is(v45.get_bool(), true, "1234567890 || 1200 --> true"); Variant v50 = v5 || v0; - t.is (v50.type (), Variant::type_boolean, "1200 || true --> boolean"); - t.is (v50.get_bool (), true, "1200 || true --> true"); + t.is(v50.type(), Variant::type_boolean, "1200 || true --> boolean"); + t.is(v50.get_bool(), true, "1200 || true --> true"); Variant v51 = v5 || v1; - t.is (v51.type (), Variant::type_boolean, "1200 || 42 --> boolean"); - t.is (v51.get_bool (), true, "1200 || 42 --> true"); + t.is(v51.type(), Variant::type_boolean, "1200 || 42 --> boolean"); + t.is(v51.get_bool(), true, "1200 || 42 --> true"); Variant v52 = v5 || v2; - t.is (v52.type (), Variant::type_boolean, "1200 || 3.14 --> boolean"); - t.is (v52.get_bool (), true, "1200 || 3.14 --> true"); + t.is(v52.type(), Variant::type_boolean, "1200 || 3.14 --> boolean"); + t.is(v52.get_bool(), true, "1200 || 3.14 --> true"); Variant v53 = v5 || v3; - t.is (v53.type (), Variant::type_boolean, "1200 || 'foo' --> boolean"); - t.is (v53.get_bool (), true, "1200 || 'foo' --> true"); + t.is(v53.type(), Variant::type_boolean, "1200 || 'foo' --> boolean"); + t.is(v53.get_bool(), true, "1200 || 'foo' --> true"); Variant v54 = v5 || v4; - t.is (v04.type (), Variant::type_boolean, "1200 || 1234567890 --> boolean"); - t.is (v04.get_bool (), true, "1200 || 1234567890 --> true"); + t.is(v04.type(), Variant::type_boolean, "1200 || 1234567890 --> boolean"); + t.is(v04.get_bool(), true, "1200 || 1234567890 --> true"); Variant v55 = v5 || v5; - t.is (v55.type (), Variant::type_boolean, "1200 || 1200 --> boolean"); - t.is (v55.get_bool (), true, "1200 || 1200 --> true"); + t.is(v55.type(), Variant::type_boolean, "1200 || 1200 --> boolean"); + t.is(v55.get_bool(), true, "1200 || 1200 --> true"); return 0; } diff --git a/test/variant_partial.test.cpp b/test/variant_partial.test.cpp index 66b6385cf..78893c4a6 100644 --- a/test/variant_partial.test.cpp +++ b/test/variant_partial.test.cpp @@ -27,175 +27,175 @@ #include // cmake.h include header must come first -#include -#include #include +#include + +#include //////////////////////////////////////////////////////////////////////////////// -int main (int, char**) -{ - UnitTest t (72); +int main(int, char**) { + UnitTest t(72); - Variant v0 (true); - Variant v1 (42); - Variant v2 (3.14); - Variant v3 ("foo"); - Variant v4 (1234567890, Variant::type_date); - Variant v5 (1200, Variant::type_duration); - Variant v6 (1234522800, Variant::type_date); // 2009-02-13, 12.00pm UTC - Variant v7 ("2009-02-13"); + Variant v0(true); + Variant v1(42); + Variant v2(3.14); + Variant v3("foo"); + Variant v4(1234567890, Variant::type_date); + Variant v5(1200, Variant::type_duration); + Variant v6(1234522800, Variant::type_date); // 2009-02-13, 12.00pm UTC + Variant v7("2009-02-13"); - Variant v00 = v0.operator_partial (v0); - t.is (v00.type (), Variant::type_boolean, "true == true --> boolean"); - t.is (v00.get_bool (), true, "true == true --> true"); + Variant v00 = v0.operator_partial(v0); + t.is(v00.type(), Variant::type_boolean, "true == true --> boolean"); + t.is(v00.get_bool(), true, "true == true --> true"); - Variant v01 = v0.operator_partial (v1); - t.is (v01.type (), Variant::type_boolean, "true == 42 --> boolean"); - t.is (v01.get_bool (), false, "true == 42 --> false"); + Variant v01 = v0.operator_partial(v1); + t.is(v01.type(), Variant::type_boolean, "true == 42 --> boolean"); + t.is(v01.get_bool(), false, "true == 42 --> false"); - Variant v02 = v0.operator_partial (v2); - t.is (v02.type (), Variant::type_boolean, "true == 3.14 --> boolean"); - t.is (v02.get_bool (), false, "true == 3.14 --> false"); + Variant v02 = v0.operator_partial(v2); + t.is(v02.type(), Variant::type_boolean, "true == 3.14 --> boolean"); + t.is(v02.get_bool(), false, "true == 3.14 --> false"); - Variant v03 = v0.operator_partial (v3); - t.is (v03.type (), Variant::type_boolean, "true == 'foo' --> boolean"); - t.is (v03.get_bool (), false, "true == 'foo' --> false"); + Variant v03 = v0.operator_partial(v3); + t.is(v03.type(), Variant::type_boolean, "true == 'foo' --> boolean"); + t.is(v03.get_bool(), false, "true == 'foo' --> false"); - Variant v04 = v0.operator_partial (v4); - t.is (v04.type (), Variant::type_boolean, "true == 1234567890 --> boolean"); - t.is (v04.get_bool (), false, "true == 1234567890 --> false"); + Variant v04 = v0.operator_partial(v4); + t.is(v04.type(), Variant::type_boolean, "true == 1234567890 --> boolean"); + t.is(v04.get_bool(), false, "true == 1234567890 --> false"); - Variant v05 = v0.operator_partial (v5); - t.is (v05.type (), Variant::type_boolean, "true == 1200 --> boolean"); - t.is (v05.get_bool (), false, "true == 1200 --> false"); + Variant v05 = v0.operator_partial(v5); + t.is(v05.type(), Variant::type_boolean, "true == 1200 --> boolean"); + t.is(v05.get_bool(), false, "true == 1200 --> false"); - Variant v10 = v1.operator_partial (v0); - t.is (v10.type (), Variant::type_boolean, "42 == true --> boolean"); - t.is (v10.get_bool (), false, "42 == true --> false"); + Variant v10 = v1.operator_partial(v0); + t.is(v10.type(), Variant::type_boolean, "42 == true --> boolean"); + t.is(v10.get_bool(), false, "42 == true --> false"); - Variant v11 = v1.operator_partial (v1); - t.is (v11.type (), Variant::type_boolean, "42 == 42 --> boolean"); - t.is (v11.get_bool (), true, "42 == 42 --> true"); + Variant v11 = v1.operator_partial(v1); + t.is(v11.type(), Variant::type_boolean, "42 == 42 --> boolean"); + t.is(v11.get_bool(), true, "42 == 42 --> true"); - Variant v12 = v1.operator_partial (v2); - t.is (v12.type (), Variant::type_boolean, "42 == 3.14 --> boolean"); - t.is (v12.get_bool (), false, "42 == 3.14 --> false"); + Variant v12 = v1.operator_partial(v2); + t.is(v12.type(), Variant::type_boolean, "42 == 3.14 --> boolean"); + t.is(v12.get_bool(), false, "42 == 3.14 --> false"); - Variant v13 = v1.operator_partial (v3); - t.is (v13.type (), Variant::type_boolean, "42 == 'foo' --> boolean"); - t.is (v13.get_bool (), false, "42 == 'foo' --> false"); + Variant v13 = v1.operator_partial(v3); + t.is(v13.type(), Variant::type_boolean, "42 == 'foo' --> boolean"); + t.is(v13.get_bool(), false, "42 == 'foo' --> false"); - Variant v14 = v1.operator_partial (v4); - t.is (v04.type (), Variant::type_boolean, "42 == 1234567890 --> boolean"); - t.is (v04.get_bool (), false, "42 == 1234567890 --> false"); + Variant v14 = v1.operator_partial(v4); + t.is(v04.type(), Variant::type_boolean, "42 == 1234567890 --> boolean"); + t.is(v04.get_bool(), false, "42 == 1234567890 --> false"); - Variant v15 = v1.operator_partial (v5); - t.is (v15.type (), Variant::type_boolean, "42 == 1200 --> boolean"); - t.is (v15.get_bool (), false, "42 == 1200 --> false"); + Variant v15 = v1.operator_partial(v5); + t.is(v15.type(), Variant::type_boolean, "42 == 1200 --> boolean"); + t.is(v15.get_bool(), false, "42 == 1200 --> false"); - Variant v20 = v2.operator_partial (v0); - t.is (v20.type (), Variant::type_boolean, "3.14 == true --> boolean"); - t.is (v20.get_bool (), false, "3.14 == true --> false"); + Variant v20 = v2.operator_partial(v0); + t.is(v20.type(), Variant::type_boolean, "3.14 == true --> boolean"); + t.is(v20.get_bool(), false, "3.14 == true --> false"); - Variant v21 = v2.operator_partial (v1); - t.is (v21.type (), Variant::type_boolean, "3.14 == 42 --> boolean"); - t.is (v21.get_bool (), false, "3.14 == 42 --> false"); + Variant v21 = v2.operator_partial(v1); + t.is(v21.type(), Variant::type_boolean, "3.14 == 42 --> boolean"); + t.is(v21.get_bool(), false, "3.14 == 42 --> false"); - Variant v22 = v2.operator_partial (v2); - t.is (v22.type (), Variant::type_boolean, "3.14 == 3.14 --> boolean"); - t.is (v22.get_bool (), true, "3.14 == 3.14 --> true"); + Variant v22 = v2.operator_partial(v2); + t.is(v22.type(), Variant::type_boolean, "3.14 == 3.14 --> boolean"); + t.is(v22.get_bool(), true, "3.14 == 3.14 --> true"); - Variant v23 = v2.operator_partial (v3); - t.is (v23.type (), Variant::type_boolean, "3.14 == 'foo' --> boolean"); - t.is (v23.get_bool (), false, "3.14 == 'foo' --> false"); + Variant v23 = v2.operator_partial(v3); + t.is(v23.type(), Variant::type_boolean, "3.14 == 'foo' --> boolean"); + t.is(v23.get_bool(), false, "3.14 == 'foo' --> false"); - Variant v24 = v2.operator_partial (v4); - t.is (v24.type (), Variant::type_boolean, "3.14 == 1234567890 --> boolean"); - t.is (v24.get_bool (), false, "3.14 == 1234567890 --> false"); + Variant v24 = v2.operator_partial(v4); + t.is(v24.type(), Variant::type_boolean, "3.14 == 1234567890 --> boolean"); + t.is(v24.get_bool(), false, "3.14 == 1234567890 --> false"); - Variant v25 = v2.operator_partial (v5); - t.is (v25.type (), Variant::type_boolean, "3.14 == 1200 --> boolean"); - t.is (v25.get_bool (), false, "3.14 == 1200 --> false"); + Variant v25 = v2.operator_partial(v5); + t.is(v25.type(), Variant::type_boolean, "3.14 == 1200 --> boolean"); + t.is(v25.get_bool(), false, "3.14 == 1200 --> false"); - Variant v30 = v3.operator_partial (v0); - t.is (v30.type (), Variant::type_boolean, "'foo' == true --> boolean"); - t.is (v30.get_bool (), false, "'foo' == true --> false"); + Variant v30 = v3.operator_partial(v0); + t.is(v30.type(), Variant::type_boolean, "'foo' == true --> boolean"); + t.is(v30.get_bool(), false, "'foo' == true --> false"); - Variant v31 = v3.operator_partial (v1); - t.is (v31.type (), Variant::type_boolean, "'foo' == 42 --> boolean"); - t.is (v31.get_bool (), false, "'foo' == 42 --> false"); + Variant v31 = v3.operator_partial(v1); + t.is(v31.type(), Variant::type_boolean, "'foo' == 42 --> boolean"); + t.is(v31.get_bool(), false, "'foo' == 42 --> false"); - Variant v32 = v3.operator_partial (v2); - t.is (v32.type (), Variant::type_boolean, "'foo' == 3.14 --> boolean"); - t.is (v32.get_bool (), false, "'foo' == 3.14 --> false"); + Variant v32 = v3.operator_partial(v2); + t.is(v32.type(), Variant::type_boolean, "'foo' == 3.14 --> boolean"); + t.is(v32.get_bool(), false, "'foo' == 3.14 --> false"); - Variant v33 = v3.operator_partial (v3); - t.is (v33.type (), Variant::type_boolean, "'foo' == 'foo' --> boolean"); - t.is (v33.get_bool (), true, "'foo' == 'foo' --> true"); + Variant v33 = v3.operator_partial(v3); + t.is(v33.type(), Variant::type_boolean, "'foo' == 'foo' --> boolean"); + t.is(v33.get_bool(), true, "'foo' == 'foo' --> true"); - Variant v34 = v3.operator_partial (v4); - t.is (v34.type (), Variant::type_boolean, "'foo' == 1234567890 --> boolean"); - t.is (v34.get_bool (), false, "'foo' == 1234567890 --> false"); + Variant v34 = v3.operator_partial(v4); + t.is(v34.type(), Variant::type_boolean, "'foo' == 1234567890 --> boolean"); + t.is(v34.get_bool(), false, "'foo' == 1234567890 --> false"); - Variant v35 = v3.operator_partial (v5); - t.is (v35.type (), Variant::type_boolean, "'foo' == 1200 --> boolean"); - t.is (v35.get_bool (), false, "'foo' == 1200 --> false"); + Variant v35 = v3.operator_partial(v5); + t.is(v35.type(), Variant::type_boolean, "'foo' == 1200 --> boolean"); + t.is(v35.get_bool(), false, "'foo' == 1200 --> false"); - Variant v40 = v4.operator_partial (v0); - t.is (v40.type (), Variant::type_boolean, "1234567890 == true --> boolean"); - t.is (v40.get_bool (), false, "1234567890 == true --> false"); + Variant v40 = v4.operator_partial(v0); + t.is(v40.type(), Variant::type_boolean, "1234567890 == true --> boolean"); + t.is(v40.get_bool(), false, "1234567890 == true --> false"); - Variant v41 = v4.operator_partial (v1); - t.is (v41.type (), Variant::type_boolean, "1234567890 == 42 --> boolean"); - t.is (v41.get_bool (), false, "1234567890 == 42 --> false"); + Variant v41 = v4.operator_partial(v1); + t.is(v41.type(), Variant::type_boolean, "1234567890 == 42 --> boolean"); + t.is(v41.get_bool(), false, "1234567890 == 42 --> false"); - Variant v42 = v4.operator_partial (v2); - t.is (v42.type (), Variant::type_boolean, "1234567890 == 3.14 --> boolean"); - t.is (v42.get_bool (), false, "1234567890 == 3.14 --> false"); + Variant v42 = v4.operator_partial(v2); + t.is(v42.type(), Variant::type_boolean, "1234567890 == 3.14 --> boolean"); + t.is(v42.get_bool(), false, "1234567890 == 3.14 --> false"); - Variant v43 = v4.operator_partial (v3); - t.is (v43.type (), Variant::type_boolean, "1234567890 == 'foo' --> boolean"); - t.is (v43.get_bool (), false, "1234567890 == 'foo' --> false"); + Variant v43 = v4.operator_partial(v3); + t.is(v43.type(), Variant::type_boolean, "1234567890 == 'foo' --> boolean"); + t.is(v43.get_bool(), false, "1234567890 == 'foo' --> false"); - Variant v44 = v4.operator_partial (v4); - t.is (v44.type (), Variant::type_boolean, "1234567890 == 1234567890 --> boolean"); - t.is (v44.get_bool (), true, "1234567890 == 1234567890 --> true"); + Variant v44 = v4.operator_partial(v4); + t.is(v44.type(), Variant::type_boolean, "1234567890 == 1234567890 --> boolean"); + t.is(v44.get_bool(), true, "1234567890 == 1234567890 --> true"); - Variant v45 = v4.operator_partial (v5); - t.is (v45.type (), Variant::type_boolean, "1234567890 == 1200 --> boolean"); - t.is (v45.get_bool (), false, "1234567890 == 1200 --> false"); + Variant v45 = v4.operator_partial(v5); + t.is(v45.type(), Variant::type_boolean, "1234567890 == 1200 --> boolean"); + t.is(v45.get_bool(), false, "1234567890 == 1200 --> false"); - Variant v50 = v5.operator_partial (v0); - t.is (v50.type (), Variant::type_boolean, "1200 == true --> boolean"); - t.is (v50.get_bool (), false, "1200 == true --> false"); + Variant v50 = v5.operator_partial(v0); + t.is(v50.type(), Variant::type_boolean, "1200 == true --> boolean"); + t.is(v50.get_bool(), false, "1200 == true --> false"); - Variant v51 = v5.operator_partial (v1); - t.is (v51.type (), Variant::type_boolean, "1200 == 42 --> boolean"); - t.is (v51.get_bool (), false, "1200 == 42 --> false"); + Variant v51 = v5.operator_partial(v1); + t.is(v51.type(), Variant::type_boolean, "1200 == 42 --> boolean"); + t.is(v51.get_bool(), false, "1200 == 42 --> false"); - Variant v52 = v5.operator_partial (v2); - t.is (v52.type (), Variant::type_boolean, "1200 == 3.14 --> boolean"); - t.is (v52.get_bool (), false, "1200 == 3.14 --> false"); + Variant v52 = v5.operator_partial(v2); + t.is(v52.type(), Variant::type_boolean, "1200 == 3.14 --> boolean"); + t.is(v52.get_bool(), false, "1200 == 3.14 --> false"); - Variant v53 = v5.operator_partial (v3); - t.is (v53.type (), Variant::type_boolean, "1200 == 'foo' --> boolean"); - t.is (v53.get_bool (), false, "1200 == 'foo' --> false"); + Variant v53 = v5.operator_partial(v3); + t.is(v53.type(), Variant::type_boolean, "1200 == 'foo' --> boolean"); + t.is(v53.get_bool(), false, "1200 == 'foo' --> false"); - Variant v54 = v5.operator_partial (v4); - t.is (v04.type (), Variant::type_boolean, "1200 == 1234567890 --> boolean"); - t.is (v04.get_bool (), false, "1200 == 1234567890 --> false"); + Variant v54 = v5.operator_partial(v4); + t.is(v04.type(), Variant::type_boolean, "1200 == 1234567890 --> boolean"); + t.is(v04.get_bool(), false, "1200 == 1234567890 --> false"); - Variant v55 = v5.operator_partial (v5); - t.is (v55.type (), Variant::type_boolean, "1200 == 1200 --> boolean"); - t.is (v55.get_bool (), true, "1200 == 1200 --> true"); + Variant v55 = v5.operator_partial(v5); + t.is(v55.type(), Variant::type_boolean, "1200 == 1200 --> boolean"); + t.is(v55.get_bool(), true, "1200 == 1200 --> true"); - Variant v56 = v6.operator_partial (v7); - t.is (v56.type (), Variant::type_boolean, "1234522800 == '2009-02-13' --> boolean"); - t.is (v56.get_bool (), true, "1234522800 == '2009-02-13' --> true"); + Variant v56 = v6.operator_partial(v7); + t.is(v56.type(), Variant::type_boolean, "1234522800 == '2009-02-13' --> boolean"); + t.is(v56.get_bool(), true, "1234522800 == '2009-02-13' --> true"); - Variant v57 = v7.operator_partial (v6); - t.is (v57.type (), Variant::type_boolean, "'2009-02-13' == 1234522800 --> boolean"); - t.is (v57.get_bool (), true, "'2009-02-13' == 1234522800 --> true"); + Variant v57 = v7.operator_partial(v6); + t.is(v57.type(), Variant::type_boolean, "'2009-02-13' == 1234522800 --> boolean"); + t.is(v57.get_bool(), true, "'2009-02-13' == 1234522800 --> true"); return 0; } diff --git a/test/variant_subtract.test.cpp b/test/variant_subtract.test.cpp index e545d4422..d0e405047 100644 --- a/test/variant_subtract.test.cpp +++ b/test/variant_subtract.test.cpp @@ -27,189 +27,253 @@ #include // cmake.h include header must come first -#include -#include #include +#include + +#include #define EPSILON 0.001 //////////////////////////////////////////////////////////////////////////////// -int main (int, char**) -{ - UnitTest t (55); +int main(int, char**) { + UnitTest t(55); - Variant v0 (true); - Variant v1 (42); - Variant v2 (3.14); - Variant v3 ("foo"); - Variant v4 (1234567890, Variant::type_date); - Variant v5 (1200, Variant::type_duration); + Variant v0(true); + Variant v1(42); + Variant v2(3.14); + Variant v3("foo"); + Variant v4(1234567890, Variant::type_date); + Variant v5(1200, Variant::type_duration); // boolean - boolean -> ERROR - try {Variant v00 = v0 - v0; t.fail ("true - true --> error");} - catch (...) {t.pass ("true - true --> error");} + try { + Variant v00 = v0 - v0; + t.fail("true - true --> error"); + } catch (...) { + t.pass("true - true --> error"); + } // boolean - integer -> ERROR - try {Variant v01 = v0 - v1; t.fail ("true - 42 --> error");} - catch (...) {t.pass ("true - 42 --> error");} + try { + Variant v01 = v0 - v1; + t.fail("true - 42 --> error"); + } catch (...) { + t.pass("true - 42 --> error"); + } // boolean - real -> ERROR - try {Variant v02 = v0 - v2; t.fail ("true - 3.14 --> error");} - catch (...) {t.pass ("true - 3.14 --> error");} + try { + Variant v02 = v0 - v2; + t.fail("true - 3.14 --> error"); + } catch (...) { + t.pass("true - 3.14 --> error"); + } // boolean - string -> ERROR - try {Variant v03 = v0 - v3; t.fail ("true - foo --> error");} - catch (...) {t.pass ("true - foo --> error");} + try { + Variant v03 = v0 - v3; + t.fail("true - foo --> error"); + } catch (...) { + t.pass("true - foo --> error"); + } // boolean - date -> ERROR - try {Variant v04 = v0 - v4; t.fail ("true - 1234567890 --> error");} - catch (...) {t.pass ("true - 1234567890 --> error");} + try { + Variant v04 = v0 - v4; + t.fail("true - 1234567890 --> error"); + } catch (...) { + t.pass("true - 1234567890 --> error"); + } // boolean - duration -> ERROR - try {Variant v05 = v0 - v5; t.fail ("true - 1200 --> error");} - catch (...) {t.pass ("true - 1200 --> error");} + try { + Variant v05 = v0 - v5; + t.fail("true - 1200 --> error"); + } catch (...) { + t.pass("true - 1200 --> error"); + } // integer - boolean -> integer Variant v10 = v1 - v0; - t.is (v10.type (), Variant::type_integer, "42 - true --> integer"); - t.is (v10.get_integer (), 41, "42 - true --> 41"); + t.is(v10.type(), Variant::type_integer, "42 - true --> integer"); + t.is(v10.get_integer(), 41, "42 - true --> 41"); // integer - integer -> integer Variant v11 = v1 - v1; - t.is (v11.type (), Variant::type_integer, "42 - 42 --> integer"); - t.is (v11.get_integer (), 0, "42 - 42 --> 0"); + t.is(v11.type(), Variant::type_integer, "42 - 42 --> integer"); + t.is(v11.get_integer(), 0, "42 - 42 --> 0"); // integer - real -> real Variant v12 = v1 - v2; - t.is (v12.type (), Variant::type_real, "42 - 3.14 --> real"); - t.is (v12.get_real (), 38.86, EPSILON, "42 - 3.14 --> 38.86"); + t.is(v12.type(), Variant::type_real, "42 - 3.14 --> real"); + t.is(v12.get_real(), 38.86, EPSILON, "42 - 3.14 --> 38.86"); // integer - string -> ERROR - try {Variant v13 = v1 - v3; t.fail ("42 - foo --> error");} - catch (...) {t.pass ("42 - foo --> error");} + try { + Variant v13 = v1 - v3; + t.fail("42 - foo --> error"); + } catch (...) { + t.pass("42 - foo --> error"); + } // integer - date -> date - Variant v1a (1300000000); + Variant v1a(1300000000); Variant v14 = v1a - v4; - t.is (v14.type (), Variant::type_date, "1300000000 - 1234567890 --> date"); - t.is (v14.get_date (), 65432110, "1300000000 - 1234567890 --> 65432110"); + t.is(v14.type(), Variant::type_date, "1300000000 - 1234567890 --> date"); + t.is(v14.get_date(), 65432110, "1300000000 - 1234567890 --> 65432110"); // integer - duration -> duration Variant v15 = v1a - v5; - t.is (v15.type (), Variant::type_duration, "1300000000 - 1200 --> duration"); - t.is (v15.get_duration (), 1299998800, "1300000000 - 1200 --> 1299998800"); + t.is(v15.type(), Variant::type_duration, "1300000000 - 1200 --> duration"); + t.is(v15.get_duration(), 1299998800, "1300000000 - 1200 --> 1299998800"); // real - boolean -> real Variant v20 = v2 - v0; - t.is (v20.type (), Variant::type_real, "3.14 - true --> real"); - t.is (v20.get_real (), 2.14, EPSILON, "3.14 - true --> 2.14"); + t.is(v20.type(), Variant::type_real, "3.14 - true --> real"); + t.is(v20.get_real(), 2.14, EPSILON, "3.14 - true --> 2.14"); // real - integer -> real Variant v21 = v2 - v1; - t.is (v21.type (), Variant::type_real, "3.14 - 42 --> real"); - t.is (v21.get_real (), -38.86, EPSILON, "3.14 - 42 --> -38.86"); + t.is(v21.type(), Variant::type_real, "3.14 - 42 --> real"); + t.is(v21.get_real(), -38.86, EPSILON, "3.14 - 42 --> -38.86"); // real - real -> real Variant v22 = v2 - v2; - t.is (v22.type (), Variant::type_real, "3.14 - 3.14 --> real"); - t.is (v22.get_real (), 0.0, EPSILON, "3.14 - 3.14 --> 0.0"); + t.is(v22.type(), Variant::type_real, "3.14 - 3.14 --> real"); + t.is(v22.get_real(), 0.0, EPSILON, "3.14 - 3.14 --> 0.0"); // real - string -> ERROR - try {Variant v23 = v1 - v3; t.fail ("3.14 - foo --> error");} - catch (...) {t.pass ("3.14 - foo --> error");} + try { + Variant v23 = v1 - v3; + t.fail("3.14 - foo --> error"); + } catch (...) { + t.pass("3.14 - foo --> error"); + } // real - date -> real - Variant v2a (1300000000.0); + Variant v2a(1300000000.0); Variant v24 = v2a - v4; - t.is (v24.type (), Variant::type_real, "1300000000.0 - 1234567890 --> real"); - t.is (v24.get_real (), 65432110.0, "1300000000.0 - 1234567890 --> 65432110"); + t.is(v24.type(), Variant::type_real, "1300000000.0 - 1234567890 --> real"); + t.is(v24.get_real(), 65432110.0, "1300000000.0 - 1234567890 --> 65432110"); // real - duration -> real Variant v25 = v2a - v5; - t.is (v25.type (), Variant::type_real, "1300000000.0 - 1200 --> real"); - t.is (v25.get_real (), 1299998800.0, "1300000000.0 - 1200 --> 1299998800"); + t.is(v25.type(), Variant::type_real, "1300000000.0 - 1200 --> real"); + t.is(v25.get_real(), 1299998800.0, "1300000000.0 - 1200 --> 1299998800"); // string - boolean -> ERROR - try {Variant v30 = v3 - v0; t.fail ("foo - foo --> error");} - catch (...) {t.pass ("foo - foo --> error");} + try { + Variant v30 = v3 - v0; + t.fail("foo - foo --> error"); + } catch (...) { + t.pass("foo - foo --> error"); + } // string - integer -> ERROR - try {Variant v31 = v3 - v1; t.fail ("foo - 42 --> error");} - catch (...) {t.pass ("foo - 42 --> error");} + try { + Variant v31 = v3 - v1; + t.fail("foo - 42 --> error"); + } catch (...) { + t.pass("foo - 42 --> error"); + } // string - real -> ERROR - try {Variant v32 = v3 - v2; t.fail ("foo - 3.14 --> error");} - catch (...) {t.pass ("foo - 3.14 --> error");} + try { + Variant v32 = v3 - v2; + t.fail("foo - 3.14 --> error"); + } catch (...) { + t.pass("foo - 3.14 --> error"); + } // string - string -> concatenated string Variant v33 = v3 - v3; - t.is (v33.type (), Variant::type_string, "foo - foo --> string"); - t.is (v33.get_string (), "foo-foo", "foo - foo --> foo-foo"); + t.is(v33.type(), Variant::type_string, "foo - foo --> string"); + t.is(v33.get_string(), "foo-foo", "foo - foo --> foo-foo"); // string - date -> ERROR - try {Variant v34 = v3 - v4; t.fail ("foo - 1234567890 --> error");} - catch (...) {t.pass ("foo - 1234567890 --> error");} + try { + Variant v34 = v3 - v4; + t.fail("foo - 1234567890 --> error"); + } catch (...) { + t.pass("foo - 1234567890 --> error"); + } // string - duration -> ERROR - try {Variant v35 = v3 - v5; t.fail ("foo - 1200 --> error");} - catch (...) {t.pass ("foo - 1200 --> error");} + try { + Variant v35 = v3 - v5; + t.fail("foo - 1200 --> error"); + } catch (...) { + t.pass("foo - 1200 --> error"); + } // date - boolean -> date Variant v40 = v4 - v0; - t.is (v40.type (), Variant::type_date, "1234567890 - true --> date"); - t.is (v40.get_date (), 1234567889, "1234567890 - true --> 1234567889"); + t.is(v40.type(), Variant::type_date, "1234567890 - true --> date"); + t.is(v40.get_date(), 1234567889, "1234567890 - true --> 1234567889"); // date - integer -> date Variant v41 = v4 - v1; - t.is (v41.type (), Variant::type_date, "1234567890 - 42 --> date"); - t.is (v41.get_date (), 1234567848, "1234567890 - 42 --> 1234567848"); + t.is(v41.type(), Variant::type_date, "1234567890 - 42 --> date"); + t.is(v41.get_date(), 1234567848, "1234567890 - 42 --> 1234567848"); // date - real -> date Variant v42 = v4 - v2; - t.is (v42.type (), Variant::type_date, "1234567890 - 3.14 --> date"); - t.is (v42.get_date (), 1234567887, "1234567890 - 3.14 --> 1234567887"); + t.is(v42.type(), Variant::type_date, "1234567890 - 3.14 --> date"); + t.is(v42.get_date(), 1234567887, "1234567890 - 3.14 --> 1234567887"); // date - string -> string - try {Variant v43 = v4 - v3; t.fail ("1234567890 - foo --> error");} - catch (...) {t.pass ("1234567890 - foo --> error");} + try { + Variant v43 = v4 - v3; + t.fail("1234567890 - foo --> error"); + } catch (...) { + t.pass("1234567890 - foo --> error"); + } // date - date -> duration Variant v44 = v4 - v4; - t.is (v44.type (), Variant::type_duration, "1234567890 - 1234567890 --> duration"); - t.is (v44.get_duration (), 0, "1234567890 - 1234567890 --> 0"); + t.is(v44.type(), Variant::type_duration, "1234567890 - 1234567890 --> duration"); + t.is(v44.get_duration(), 0, "1234567890 - 1234567890 --> 0"); // date - duration -> date Variant v45 = v4 - v5; - t.is (v45.type (), Variant::type_date, "1234567890 - 1200 --> date"); - t.is (v45.get_date (), 1234566690, "1234567890 - 1200 --> 1234566690"); + t.is(v45.type(), Variant::type_date, "1234567890 - 1200 --> date"); + t.is(v45.get_date(), 1234566690, "1234567890 - 1200 --> 1234566690"); // duration - boolean -> duration Variant v50 = v5 - v0; - t.is (v50.type (), Variant::type_duration, "1200 - true --> duration"); - t.is (v50.get_duration (), 1199, "1200 - true --> 1199"); + t.is(v50.type(), Variant::type_duration, "1200 - true --> duration"); + t.is(v50.get_duration(), 1199, "1200 - true --> 1199"); // duration - integer -> duration Variant v51 = v5 - v1; - t.is (v51.type (), Variant::type_duration, "1200 - 42 --> duration"); - t.is (v51.get_duration (), 1158, "1200 - 42 --> 1158"); + t.is(v51.type(), Variant::type_duration, "1200 - 42 --> duration"); + t.is(v51.get_duration(), 1158, "1200 - 42 --> 1158"); // duration - real -> duration Variant v52 = v5 - v2; - t.is (v52.type (), Variant::type_duration, "1200 - 3.14 --> duration"); - t.is (v52.get_duration (), 1197, "1200 - 3.14 --> 1197"); + t.is(v52.type(), Variant::type_duration, "1200 - 3.14 --> duration"); + t.is(v52.get_duration(), 1197, "1200 - 3.14 --> 1197"); // duration - string -> ERROR - try {Variant v53 = v5 - v3; t.fail ("1200 - foo --> error");} - catch (...) {t.pass ("1200 - foo --> error");} + try { + Variant v53 = v5 - v3; + t.fail("1200 - foo --> error"); + } catch (...) { + t.pass("1200 - foo --> error"); + } // duration - date -> ERROR - try {Variant v54 = v5 - v4; t.fail ("1200 - 1234567890 --> error");} - catch (...) {t.pass ("1200 - 1234567890 --> error");} + try { + Variant v54 = v5 - v4; + t.fail("1200 - 1234567890 --> error"); + } catch (...) { + t.pass("1200 - 1234567890 --> error"); + } // duration - duration -> duration Variant v55 = v5 - v5; - t.is (v55.type (), Variant::type_duration, "1200 - 1200 --> duration"); - t.is (v55.get_duration (), 0, "1200 - 1200 --> 0"); + t.is(v55.type(), Variant::type_duration, "1200 - 1200 --> duration"); + t.is(v55.get_duration(), 0, "1200 - 1200 --> 0"); return 0; } diff --git a/test/variant_xor.test.cpp b/test/variant_xor.test.cpp index cd32ee24f..3e15fd212 100644 --- a/test/variant_xor.test.cpp +++ b/test/variant_xor.test.cpp @@ -27,173 +27,173 @@ #include // cmake.h include header must come first -#include -#include #include +#include + +#include //////////////////////////////////////////////////////////////////////////////// -int main (int, char**) -{ - UnitTest t (76); +int main(int, char**) { + UnitTest t(76); - Variant v0 (true); - Variant v1 (42); - Variant v2 (3.14); - Variant v3 ("foo"); - Variant v4 (1234567890, Variant::type_date); - Variant v5 (1200, Variant::type_duration); + Variant v0(true); + Variant v1(42); + Variant v2(3.14); + Variant v3("foo"); + Variant v4(1234567890, Variant::type_date); + Variant v5(1200, Variant::type_duration); // Truth table. - Variant vFalse (false); - Variant vTrue (true); - t.is (vFalse.operator_xor (vFalse), false, "false xor false --> false"); - t.is (vFalse.operator_xor (vTrue), true, "false xor true --> false"); - t.is (vTrue.operator_xor (vFalse), true, "true xor false --> false"); - t.is (vTrue.operator_xor (vTrue), false, "true xor true --> false"); + Variant vFalse(false); + Variant vTrue(true); + t.is(vFalse.operator_xor(vFalse), false, "false xor false --> false"); + t.is(vFalse.operator_xor(vTrue), true, "false xor true --> false"); + t.is(vTrue.operator_xor(vFalse), true, "true xor false --> false"); + t.is(vTrue.operator_xor(vTrue), false, "true xor true --> false"); - Variant v00 = v0.operator_xor (v0); - t.is (v00.type (), Variant::type_boolean, "true xor true --> boolean"); - t.is (v00.get_bool (), false, "true xor true --> false"); + Variant v00 = v0.operator_xor(v0); + t.is(v00.type(), Variant::type_boolean, "true xor true --> boolean"); + t.is(v00.get_bool(), false, "true xor true --> false"); - Variant v01 = v0.operator_xor (v1); - t.is (v01.type (), Variant::type_boolean, "true xor 42 --> boolean"); - t.is (v01.get_bool (), false, "true xor 42 --> false"); + Variant v01 = v0.operator_xor(v1); + t.is(v01.type(), Variant::type_boolean, "true xor 42 --> boolean"); + t.is(v01.get_bool(), false, "true xor 42 --> false"); - Variant v02 = v0.operator_xor (v2); - t.is (v02.type (), Variant::type_boolean, "true xor 3.14 --> boolean"); - t.is (v02.get_bool (), false, "true xor 3.14 --> false"); + Variant v02 = v0.operator_xor(v2); + t.is(v02.type(), Variant::type_boolean, "true xor 3.14 --> boolean"); + t.is(v02.get_bool(), false, "true xor 3.14 --> false"); - Variant v03 = v0.operator_xor (v3); - t.is (v03.type (), Variant::type_boolean, "true xor 'foo' --> boolean"); - t.is (v03.get_bool (), false, "true xor 'foo' --> false"); + Variant v03 = v0.operator_xor(v3); + t.is(v03.type(), Variant::type_boolean, "true xor 'foo' --> boolean"); + t.is(v03.get_bool(), false, "true xor 'foo' --> false"); - Variant v04 = v0.operator_xor (v4); - t.is (v04.type (), Variant::type_boolean, "true xor 1234567890 --> boolean"); - t.is (v04.get_bool (), false, "true xor 1234567890 --> false"); + Variant v04 = v0.operator_xor(v4); + t.is(v04.type(), Variant::type_boolean, "true xor 1234567890 --> boolean"); + t.is(v04.get_bool(), false, "true xor 1234567890 --> false"); - Variant v05 = v0.operator_xor (v5); - t.is (v05.type (), Variant::type_boolean, "true xor 1200 --> boolean"); - t.is (v05.get_bool (), false, "true xor 1200 --> false"); + Variant v05 = v0.operator_xor(v5); + t.is(v05.type(), Variant::type_boolean, "true xor 1200 --> boolean"); + t.is(v05.get_bool(), false, "true xor 1200 --> false"); - Variant v10 = v1.operator_xor (v0); - t.is (v10.type (), Variant::type_boolean, "42 xor true --> boolean"); - t.is (v10.get_bool (), false, "42 xor true --> false"); + Variant v10 = v1.operator_xor(v0); + t.is(v10.type(), Variant::type_boolean, "42 xor true --> boolean"); + t.is(v10.get_bool(), false, "42 xor true --> false"); - Variant v11 = v1.operator_xor (v1); - t.is (v11.type (), Variant::type_boolean, "42 xor 42 --> boolean"); - t.is (v11.get_bool (), false, "42 xor 42 --> false"); + Variant v11 = v1.operator_xor(v1); + t.is(v11.type(), Variant::type_boolean, "42 xor 42 --> boolean"); + t.is(v11.get_bool(), false, "42 xor 42 --> false"); - Variant v12 = v1.operator_xor (v2); - t.is (v12.type (), Variant::type_boolean, "42 xor 3.14 --> boolean"); - t.is (v12.get_bool (), false, "42 xor 3.14 --> false"); + Variant v12 = v1.operator_xor(v2); + t.is(v12.type(), Variant::type_boolean, "42 xor 3.14 --> boolean"); + t.is(v12.get_bool(), false, "42 xor 3.14 --> false"); - Variant v13 = v1.operator_xor (v3); - t.is (v13.type (), Variant::type_boolean, "42 xor 'foo' --> boolean"); - t.is (v13.get_bool (), false, "42 xor 'foo' --> false"); + Variant v13 = v1.operator_xor(v3); + t.is(v13.type(), Variant::type_boolean, "42 xor 'foo' --> boolean"); + t.is(v13.get_bool(), false, "42 xor 'foo' --> false"); - Variant v14 = v1.operator_xor (v4); - t.is (v04.type (), Variant::type_boolean, "42 xor 1234567890 --> boolean"); - t.is (v04.get_bool (), false, "42 xor 1234567890 --> false"); + Variant v14 = v1.operator_xor(v4); + t.is(v04.type(), Variant::type_boolean, "42 xor 1234567890 --> boolean"); + t.is(v04.get_bool(), false, "42 xor 1234567890 --> false"); - Variant v15 = v1.operator_xor (v5); - t.is (v15.type (), Variant::type_boolean, "42 xor 1200 --> boolean"); - t.is (v15.get_bool (), false, "42 xor 1200 --> false"); + Variant v15 = v1.operator_xor(v5); + t.is(v15.type(), Variant::type_boolean, "42 xor 1200 --> boolean"); + t.is(v15.get_bool(), false, "42 xor 1200 --> false"); - Variant v20 = v2.operator_xor (v0); - t.is (v20.type (), Variant::type_boolean, "3.14 xor true --> boolean"); - t.is (v20.get_bool (), false, "3.14 xor true --> false"); + Variant v20 = v2.operator_xor(v0); + t.is(v20.type(), Variant::type_boolean, "3.14 xor true --> boolean"); + t.is(v20.get_bool(), false, "3.14 xor true --> false"); - Variant v21 = v2.operator_xor (v1); - t.is (v21.type (), Variant::type_boolean, "3.14 xor 42 --> boolean"); - t.is (v21.get_bool (), false, "3.14 xor 42 --> false"); + Variant v21 = v2.operator_xor(v1); + t.is(v21.type(), Variant::type_boolean, "3.14 xor 42 --> boolean"); + t.is(v21.get_bool(), false, "3.14 xor 42 --> false"); - Variant v22 = v2.operator_xor (v2); - t.is (v22.type (), Variant::type_boolean, "3.14 xor 3.14 --> boolean"); - t.is (v22.get_bool (), false, "3.14 xor 3.14 --> false"); + Variant v22 = v2.operator_xor(v2); + t.is(v22.type(), Variant::type_boolean, "3.14 xor 3.14 --> boolean"); + t.is(v22.get_bool(), false, "3.14 xor 3.14 --> false"); - Variant v23 = v2.operator_xor (v3); - t.is (v23.type (), Variant::type_boolean, "3.14 xor 'foo' --> boolean"); - t.is (v23.get_bool (), false, "3.14 xor 'foo' --> false"); + Variant v23 = v2.operator_xor(v3); + t.is(v23.type(), Variant::type_boolean, "3.14 xor 'foo' --> boolean"); + t.is(v23.get_bool(), false, "3.14 xor 'foo' --> false"); - Variant v24 = v2.operator_xor (v4); - t.is (v24.type (), Variant::type_boolean, "3.14 xor 1234567890 --> boolean"); - t.is (v24.get_bool (), false, "3.14 xor 1234567890 --> false"); + Variant v24 = v2.operator_xor(v4); + t.is(v24.type(), Variant::type_boolean, "3.14 xor 1234567890 --> boolean"); + t.is(v24.get_bool(), false, "3.14 xor 1234567890 --> false"); - Variant v25 = v2.operator_xor (v5); - t.is (v25.type (), Variant::type_boolean, "3.14 xor 1200 --> boolean"); - t.is (v25.get_bool (), false, "3.14 xor 1200 --> false"); + Variant v25 = v2.operator_xor(v5); + t.is(v25.type(), Variant::type_boolean, "3.14 xor 1200 --> boolean"); + t.is(v25.get_bool(), false, "3.14 xor 1200 --> false"); - Variant v30 = v3.operator_xor (v0); - t.is (v30.type (), Variant::type_boolean, "'foo' xor true --> boolean"); - t.is (v30.get_bool (), false, "'foo' xor true --> false"); + Variant v30 = v3.operator_xor(v0); + t.is(v30.type(), Variant::type_boolean, "'foo' xor true --> boolean"); + t.is(v30.get_bool(), false, "'foo' xor true --> false"); - Variant v31 = v3.operator_xor (v1); - t.is (v31.type (), Variant::type_boolean, "'foo' xor 42 --> boolean"); - t.is (v31.get_bool (), false, "'foo' xor 42 --> false"); + Variant v31 = v3.operator_xor(v1); + t.is(v31.type(), Variant::type_boolean, "'foo' xor 42 --> boolean"); + t.is(v31.get_bool(), false, "'foo' xor 42 --> false"); - Variant v32 = v3.operator_xor (v2); - t.is (v32.type (), Variant::type_boolean, "'foo' xor 3.14 --> boolean"); - t.is (v32.get_bool (), false, "'foo' xor 3.14 --> false"); + Variant v32 = v3.operator_xor(v2); + t.is(v32.type(), Variant::type_boolean, "'foo' xor 3.14 --> boolean"); + t.is(v32.get_bool(), false, "'foo' xor 3.14 --> false"); - Variant v33 = v3.operator_xor (v3); - t.is (v33.type (), Variant::type_boolean, "'foo' xor 'foo' --> boolean"); - t.is (v33.get_bool (), false, "'foo' xor 'foo' --> false"); + Variant v33 = v3.operator_xor(v3); + t.is(v33.type(), Variant::type_boolean, "'foo' xor 'foo' --> boolean"); + t.is(v33.get_bool(), false, "'foo' xor 'foo' --> false"); - Variant v34 = v3.operator_xor (v4); - t.is (v34.type (), Variant::type_boolean, "'foo' xor 1234567890 --> boolean"); - t.is (v34.get_bool (), false, "'foo' xor 1234567890 --> false"); + Variant v34 = v3.operator_xor(v4); + t.is(v34.type(), Variant::type_boolean, "'foo' xor 1234567890 --> boolean"); + t.is(v34.get_bool(), false, "'foo' xor 1234567890 --> false"); - Variant v35 = v3.operator_xor (v5); - t.is (v35.type (), Variant::type_boolean, "'foo' xor 1200 --> boolean"); - t.is (v35.get_bool (), false, "'foo' xor 1200 --> false"); + Variant v35 = v3.operator_xor(v5); + t.is(v35.type(), Variant::type_boolean, "'foo' xor 1200 --> boolean"); + t.is(v35.get_bool(), false, "'foo' xor 1200 --> false"); - Variant v40 = v4.operator_xor (v0); - t.is (v40.type (), Variant::type_boolean, "1234567890 xor true --> boolean"); - t.is (v40.get_bool (), false, "1234567890 xor true --> false"); + Variant v40 = v4.operator_xor(v0); + t.is(v40.type(), Variant::type_boolean, "1234567890 xor true --> boolean"); + t.is(v40.get_bool(), false, "1234567890 xor true --> false"); - Variant v41 = v4.operator_xor (v1); - t.is (v41.type (), Variant::type_boolean, "1234567890 xor 42 --> boolean"); - t.is (v41.get_bool (), false, "1234567890 xor 42 --> false"); + Variant v41 = v4.operator_xor(v1); + t.is(v41.type(), Variant::type_boolean, "1234567890 xor 42 --> boolean"); + t.is(v41.get_bool(), false, "1234567890 xor 42 --> false"); - Variant v42 = v4.operator_xor (v2); - t.is (v42.type (), Variant::type_boolean, "1234567890 xor 3.14 --> boolean"); - t.is (v42.get_bool (), false, "1234567890 xor 3.14 --> false"); + Variant v42 = v4.operator_xor(v2); + t.is(v42.type(), Variant::type_boolean, "1234567890 xor 3.14 --> boolean"); + t.is(v42.get_bool(), false, "1234567890 xor 3.14 --> false"); - Variant v43 = v4.operator_xor (v3); - t.is (v43.type (), Variant::type_boolean, "1234567890 xor 'foo' --> boolean"); - t.is (v43.get_bool (), false, "1234567890 xor 'foo' --> false"); + Variant v43 = v4.operator_xor(v3); + t.is(v43.type(), Variant::type_boolean, "1234567890 xor 'foo' --> boolean"); + t.is(v43.get_bool(), false, "1234567890 xor 'foo' --> false"); - Variant v44 = v4.operator_xor (v4); - t.is (v44.type (), Variant::type_boolean, "1234567890 xor 1234567890 --> boolean"); - t.is (v44.get_bool (), false, "1234567890 xor 1234567890 --> false"); + Variant v44 = v4.operator_xor(v4); + t.is(v44.type(), Variant::type_boolean, "1234567890 xor 1234567890 --> boolean"); + t.is(v44.get_bool(), false, "1234567890 xor 1234567890 --> false"); - Variant v45 = v4.operator_xor (v5); - t.is (v45.type (), Variant::type_boolean, "1234567890 xor 1200 --> boolean"); - t.is (v45.get_bool (), false, "1234567890 xor 1200 --> false"); + Variant v45 = v4.operator_xor(v5); + t.is(v45.type(), Variant::type_boolean, "1234567890 xor 1200 --> boolean"); + t.is(v45.get_bool(), false, "1234567890 xor 1200 --> false"); - Variant v50 = v5.operator_xor (v0); - t.is (v50.type (), Variant::type_boolean, "1200 xor true --> boolean"); - t.is (v50.get_bool (), false, "1200 xor true --> false"); + Variant v50 = v5.operator_xor(v0); + t.is(v50.type(), Variant::type_boolean, "1200 xor true --> boolean"); + t.is(v50.get_bool(), false, "1200 xor true --> false"); - Variant v51 = v5.operator_xor (v1); - t.is (v51.type (), Variant::type_boolean, "1200 xor 42 --> boolean"); - t.is (v51.get_bool (), false, "1200 xor 42 --> false"); + Variant v51 = v5.operator_xor(v1); + t.is(v51.type(), Variant::type_boolean, "1200 xor 42 --> boolean"); + t.is(v51.get_bool(), false, "1200 xor 42 --> false"); - Variant v52 = v5.operator_xor (v2); - t.is (v52.type (), Variant::type_boolean, "1200 xor 3.14 --> boolean"); - t.is (v52.get_bool (), false, "1200 xor 3.14 --> false"); + Variant v52 = v5.operator_xor(v2); + t.is(v52.type(), Variant::type_boolean, "1200 xor 3.14 --> boolean"); + t.is(v52.get_bool(), false, "1200 xor 3.14 --> false"); - Variant v53 = v5.operator_xor (v3); - t.is (v53.type (), Variant::type_boolean, "1200 xor 'foo' --> boolean"); - t.is (v53.get_bool (), false, "1200 xor 'foo' --> false"); + Variant v53 = v5.operator_xor(v3); + t.is(v53.type(), Variant::type_boolean, "1200 xor 'foo' --> boolean"); + t.is(v53.get_bool(), false, "1200 xor 'foo' --> false"); - Variant v54 = v5.operator_xor (v4); - t.is (v04.type (), Variant::type_boolean, "1200 xor 1234567890 --> boolean"); - t.is (v04.get_bool (), false, "1200 xor 1234567890 --> false"); + Variant v54 = v5.operator_xor(v4); + t.is(v04.type(), Variant::type_boolean, "1200 xor 1234567890 --> boolean"); + t.is(v04.get_bool(), false, "1200 xor 1234567890 --> false"); - Variant v55 = v5.operator_xor (v5); - t.is (v55.type (), Variant::type_boolean, "1200 xor 1200 --> boolean"); - t.is (v55.get_bool (), false, "1200 xor 1200 --> false"); + Variant v55 = v5.operator_xor(v5); + t.is(v55.type(), Variant::type_boolean, "1200 xor 1200 --> boolean"); + t.is(v55.get_bool(), false, "1200 xor 1200 --> false"); return 0; } diff --git a/test/verbose.test.py b/test/verbose.test.py index b38ae25de..06b8b69bf 100755 --- a/test/verbose.test.py +++ b/test/verbose.test.py @@ -57,14 +57,16 @@ class TestVerbosity(TestCase): def test_verbosity_new_uuid(self): """Verbosity new-uuid""" code, out, err = self.t(("rc.verbose:new-uuid", "add", "Sample1")) - self.assertRegex(out, r"Created task [0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}") + self.assertRegex( + out, + r"Created task [0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}", + ) def test_verbosity_label(self): """Verbosity label""" code, out, err = self.t("rc.verbose:label ls") self.assertRegex( - out, - "ID.+A.+D.+Project.+Tags.+R.+Wait.+S.+Due.+Until.+Description" + out, "ID.+A.+D.+Project.+Tags.+R.+Wait.+S.+Due.+Until.+Description" ) def test_verbosity_affected(self): @@ -86,14 +88,17 @@ class TestVerbosity(TestCase): """Verbosity special""" code, out, err = self.t("rc.verbose:special 1 mod +next") - self.assertIn("The 'next' special tag will boost the urgency of this " - "task so it appears on the 'next' report.", out) + self.assertIn( + "The 'next' special tag will boost the urgency of this " + "task so it appears on the 'next' report.", + out, + ) def test_verbosity_blank(self): """Verbosity blank""" def count_blank_lines(x): - return x.splitlines().count('') + return x.splitlines().count("") code, out, err = self.t("rc.verbose:nothing ls") self.assertEqual(count_blank_lines(out), 0) @@ -142,6 +147,7 @@ class TestVerbosity(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/version.test.py b/test/version.test.py index 3d74bd1c7..6d751a643 100755 --- a/test/version.test.py +++ b/test/version.test.py @@ -30,6 +30,7 @@ import os import unittest import re from datetime import datetime + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -58,7 +59,7 @@ class TestVersion(TestCase): def slurp(self, file=os.path.join(SOURCE_DIR, "CMakeLists.txt")): number = "\.".join(["[0-9]+"] * 3) - ver = re.compile("^ *VERSION ({0}[^\"]*)$".format(number)) + ver = re.compile('^ *VERSION ({0}[^"]*)$'.format(number)) with open(file) as fh: for line in fh: match = ver.match(line) @@ -85,12 +86,11 @@ class TestVersion(TestCase): # If we are within a git repository, check the tag version if os.path.exists("../.git"): - if 2 >= len(version) > 0: - git = version[1] - self.assertRegex(git, r'\([a-f0-9]*\)') - else: - raise ValueError("Unexpected output from _version '{0}'".format( - out)) + if 2 >= len(version) > 0: + git = version[1] + self.assertRegex(git, r"\([a-f0-9]*\)") + else: + raise ValueError("Unexpected output from _version '{0}'".format(out)) ver = version[0] ver_expected = self.slurp() @@ -102,11 +102,12 @@ class TestVersion(TestCase): def test_version_option(self): """Verify that 'task --version' returns something valid""" code, out, err = self.t("--version") - self.assertRegex(out, r'^\d\.\d+\.\d+(\.\w+)?$') + self.assertRegex(out, r"^\d\.\d+\.\d+(\.\w+)?$") if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/test/view.test.cpp b/test/view.test.cpp index 59f668298..0d8b05acc 100644 --- a/test/view.test.cpp +++ b/test/view.test.cpp @@ -27,138 +27,138 @@ #include // cmake.h include header must come first -#include -#include -#include -#include -#include #include +#include #include #include -#include #include +#include +#include +#include +#include + +#include Context context; extern std::string configurationDefaults; //////////////////////////////////////////////////////////////////////////////// -int main (int, char**) -{ - UnitTest t (1); +int main(int, char**) { + UnitTest t(1); Context context; Context::setContext(&context); // Ensure environment has no influence. - unsetenv ("TASKDATA"); - unsetenv ("TASKRC"); + unsetenv("TASKDATA"); + unsetenv("TASKRC"); - try - { + try { // Set up configuration. - context.config.parse (configurationDefaults); - context.config.set ("fontunderline", true); - context.config.set ("tag.indicator", "+"); - context.config.set ("dependency.indicator", "D"); - context.config.set ("recurrence.indicator", "R"); - context.config.set ("active.indicator", "A"); - context.config.set ("dateformat", "Y-M-D"); - context.config.set ("indent.annotation", "2"); + context.config.parse(configurationDefaults); + context.config.set("fontunderline", true); + context.config.set("tag.indicator", "+"); + context.config.set("dependency.indicator", "D"); + context.config.set("recurrence.indicator", "R"); + context.config.set("active.indicator", "A"); + context.config.set("dateformat", "Y-M-D"); + context.config.set("indent.annotation", "2"); // Two sample tasks. t.ok(true, "zero"); - Task t1 ("{" - "\"status\":\"pending\", " - "\"uuid\":\"2a64f6e0-bf8e-430d-bf71-9ec3f0d9b661\", " - "\"description\":\"This is the description text\", " - "\"project\":\"Home\", " - "\"priority\":\"H\", " - "\"annotation_1234567890\":\"This is an annotation\", " - "\"start\":\"1234567890\", " - "\"due\":\"1234567890\", " - "\"tags\":\"one,two\"" - "}"); + Task t1( + "{" + "\"status\":\"pending\", " + "\"uuid\":\"2a64f6e0-bf8e-430d-bf71-9ec3f0d9b661\", " + "\"description\":\"This is the description text\", " + "\"project\":\"Home\", " + "\"priority\":\"H\", " + "\"annotation_1234567890\":\"This is an annotation\", " + "\"start\":\"1234567890\", " + "\"due\":\"1234567890\", " + "\"tags\":\"one,two\"" + "}"); t1.id = 1; t.ok(true, "one"); - Task t2 ("{" - "\"status\":\"pending\", " - "\"uuid\":\"f30cb9c3-3fc0-483f-bfb2-3bf134f00694\", " - "\"description\":\"This is the description text\", " - "\"project\":\"Garden Care\", " - "\"recur\":\"monthly\", " - "\"depends\":\"2a64f6e0-bf8e-430d-bf71-9ec3f0d9b661\"" - "}"); + Task t2( + "{" + "\"status\":\"pending\", " + "\"uuid\":\"f30cb9c3-3fc0-483f-bfb2-3bf134f00694\", " + "\"description\":\"This is the description text\", " + "\"project\":\"Garden Care\", " + "\"recur\":\"monthly\", " + "\"depends\":\"2a64f6e0-bf8e-430d-bf71-9ec3f0d9b661\"" + "}"); t2.id = 11; t.ok(true, "two"); - Task t3 ("{" - "\"status\":\"pending\", " - "\"uuid\":\"c44cb9c3-3fc0-483f-bfb2-3bf134f05554\", " - "\"description\":\"Another description\", " - "\"project\":\"Garden\"" - "}"); + Task t3( + "{" + "\"status\":\"pending\", " + "\"uuid\":\"c44cb9c3-3fc0-483f-bfb2-3bf134f05554\", " + "\"description\":\"Another description\", " + "\"project\":\"Garden\"" + "}"); t3.id = 8; t.ok(true, "three"); - std::vector data; - data.push_back (t1); - data.push_back (t2); - data.push_back (t3); + std::vector data; + data.push_back(t1); + data.push_back(t2); + data.push_back(t3); // Sequence of tasks. - std::vector sequence; - sequence.push_back (0); - sequence.push_back (1); - sequence.push_back (2); + std::vector sequence; + sequence.push_back(0); + sequence.push_back(1); + sequence.push_back(2); - sort_tasks (data, sequence, "description+,id-"); + sort_tasks(data, sequence, "description+,id-"); // Create colors. - Color header_color (Color (Color::yellow, Color::nocolor, false, false, false)); - Color odd_color ("on gray1"); - Color even_color ("on gray0"); + Color header_color(Color(Color::yellow, Color::nocolor, false, false, false)); + Color odd_color("on gray1"); + Color even_color("on gray0"); // Create a view. std::string report = "view.t"; ViewTask view; - view.add (Column::factory ("id", report)); - view.add (Column::factory ("uuid.short", report)); - view.add (Column::factory ("project", report)); - view.add (Column::factory ("priority", report)); - view.add (Column::factory ("tags", report)); - view.add (Column::factory ("tags.count", report)); - view.add (Column::factory ("description", report)); - view.add (Column::factory ("depends.indicator", report)); - view.add (Column::factory ("recur.indicator", report)); - view.add (Column::factory ("status.short", report)); - view.add (Column::factory ("due.countdown", report)); - view.add (Column::factory ("start.active", report)); - view.add (Column::factory ("urgency", report)); - view.width (context.getWidth ()); - view.leftMargin (4); - view.extraPadding (0); - view.intraPadding (1); - view.colorHeader (header_color); - view.colorOdd (odd_color); - view.colorEven (even_color); - view.intraColorOdd (odd_color); - view.intraColorEven (even_color); + view.add(Column::factory("id", report)); + view.add(Column::factory("uuid.short", report)); + view.add(Column::factory("project", report)); + view.add(Column::factory("priority", report)); + view.add(Column::factory("tags", report)); + view.add(Column::factory("tags.count", report)); + view.add(Column::factory("description", report)); + view.add(Column::factory("depends.indicator", report)); + view.add(Column::factory("recur.indicator", report)); + view.add(Column::factory("status.short", report)); + view.add(Column::factory("due.countdown", report)); + view.add(Column::factory("start.active", report)); + view.add(Column::factory("urgency", report)); + view.width(context.getWidth()); + view.leftMargin(4); + view.extraPadding(0); + view.intraPadding(1); + view.colorHeader(header_color); + view.colorOdd(odd_color); + view.colorEven(even_color); + view.intraColorOdd(odd_color); + view.intraColorEven(even_color); // Render the view. - std::cout << view.render (data, sequence); + std::cout << view.render(data, sequence); int expected_lines = 5; - if (!isatty (fileno (stdout))) - expected_lines = 6; + if (!isatty(fileno(stdout))) expected_lines = 6; - t.is (view.lines (), expected_lines, "View::lines == 5"); + t.is(view.lines(), expected_lines, "View::lines == 5"); // Now render a string-only grid. - context.config.set ("fontunderline", false); - Color single_cell ("bold white on red"); + context.config.set("fontunderline", false); + Color single_cell("bold white on red"); } - catch (const std::string& e) - { - t.fail ("Exception thrown."); - t.diag (e); + catch (const std::string& e) { + t.fail("Exception thrown."); + t.diag(e); } return 0; diff --git a/test/wait.test.py b/test/wait.test.py index a88f5dc76..adc609730 100755 --- a/test/wait.test.py +++ b/test/wait.test.py @@ -28,6 +28,7 @@ import sys import os import unittest + # Ensure python finds the local simpletap module sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -86,19 +87,19 @@ class Test1486(TestCase): def test_waiting(self): """1486: Verify waiting report shows waiting tasks""" - self.t('add regular') - self.t('add waited and pending wait:later') - self.t('add waited but deleted wait:later') - self.t('add waited but done wait:later') - self.t('rc.confirmation=off 3 delete') - self.t('4 done') + self.t("add regular") + self.t("add waited and pending wait:later") + self.t("add waited but deleted wait:later") + self.t("add waited but done wait:later") + self.t("rc.confirmation=off 3 delete") + self.t("4 done") - code, out, err = self.t('waiting') + code, out, err = self.t("waiting") self.assertEqual(0, code, "Exit code was non-zero ({0})".format(code)) - self.assertIn('waited and pending', out) - self.assertNotIn('waited but deleted', out) - self.assertNotIn('waited but done', out) - self.assertNotIn('regular', out) + self.assertIn("waited and pending", out) + self.assertNotIn("waited but deleted", out) + self.assertNotIn("waited but done", out) + self.assertNotIn("regular", out) class TestFeature2563(TestCase): @@ -129,6 +130,7 @@ class TestFeature2563(TestCase): if __name__ == "__main__": from simpletap import TAPTestRunner + unittest.main(testRunner=TAPTestRunner()) # vim: ai sts=4 et sw=4 ft=python diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml index 7bf176d4c..ffcbbe838 100644 --- a/xtask/Cargo.toml +++ b/xtask/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "xtask" -version = "0.4.1" +version = "0.4.1" edition = "2021" [dependencies]