From 9bf1ec2f7c1f3594fc44b267f5f14986e7aec50b Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Tue, 26 Jul 2011 00:37:49 -0400 Subject: [PATCH] Code Cleanup - Eliminated Lexer. --- DEVELOPER | 3 - src/CMakeLists.txt | 1 - src/Lexer.cpp | 374 ------------------------------------------- src/Lexer.h | 84 ---------- test/CMakeLists.txt | 9 +- test/arguments.t.cpp | 190 ---------------------- test/dom.t.cpp | 2 +- test/lexer.t.cpp | 331 -------------------------------------- 8 files changed, 5 insertions(+), 989 deletions(-) delete mode 100644 src/Lexer.cpp delete mode 100644 src/Lexer.h delete mode 100644 test/arguments.t.cpp delete mode 100644 test/lexer.t.cpp diff --git a/DEVELOPER b/DEVELOPER index a245e376e..bdb6feb29 100644 --- a/DEVELOPER +++ b/DEVELOPER @@ -6,13 +6,10 @@ Deprecated Code This is code that is going to be phased out "soon", and therefore is not worth fixing or documenting. - - Arguments.{h,cpp} - - Expression.{h,cpp} - Variant.{h,cpp} - Location.{h,cpp} - TDB.{h,cpp} - Att.{h,cpp} - - Lexer.{h,cpp} New Code Needs This is code that needs to be written, usually down at the C++ function level. diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 419778396..993f05a04 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -19,7 +19,6 @@ set (task_SRCS A3.cpp A3.h File.cpp File.h Hooks.cpp Hooks.h JSON.cpp JSON.h - Lexer.cpp Lexer.h Location.cpp Location.h Nibbler.cpp Nibbler.h Path.cpp Path.h diff --git a/src/Lexer.cpp b/src/Lexer.cpp deleted file mode 100644 index b74a1640b..000000000 --- a/src/Lexer.cpp +++ /dev/null @@ -1,374 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// taskwarrior - a command line task list manager. -// -// Copyright 2011, Paul Beckingham, Federico Hernandez. -// All rights reserved. -// -// This program is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free Software -// Foundation; either version 2 of the License, or (at your option) any later -// version. -// -// This program is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more -// details. -// -// You should have received a copy of the GNU General Public License along with -// this program; if not, write to the -// -// Free Software Foundation, Inc., -// 51 Franklin Street, Fifth Floor, -// Boston, MA -// 02110-1301 -// USA -// -//////////////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////////////// -// This lexer works by breaking the input stream into tokens. The essence of -// the algorithm lies in the distinction between adjacent tokens, such that -// between the two extremes lies a good solution. -// -// At one extreme, the entire input is considered one token. Clearly this is -// only correct for trivial input. At the other extreme, every character of the -// input is a token. This is also wrong. -// -// If the input is as follows: -// -// It is almost 11:00am. -// -// The desired tokenization is: -// -// It -// -// is -// -// almost -// -// 11 -// : -// 00 -// am -// . -// \n -// -// This can be achieved by allowing transitions to denote token boundaries. -// Given the following character classes: -// -// letter: a-z A-Z -// digit: 0-9 -// whitespace: -// other: Everything else -// -// Then a token boundary is a transition between: -// letter -> !letter -// digit -> !digit -// whitespace -> any -// other -> any -// -// This has the effect of allowing groups of consecutive letters to be -// considered one token, as well as groups of digits. -// -//////////////////////////////////////////////////////////////////////////////// - -#include -#include -#include - -static const int other = -1; -static const int alpha = -2; -static const int digit = -3; -static const int white = -4; -static const int quote = -5; - -//////////////////////////////////////////////////////////////////////////////// -Lexer::Lexer (const std::string& input) -: mInput (input) - -, mAlpha ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") -, mDigit ("0123456789") -, mQuote ("'\"") -, mWhite (" \t\n\r\f") - -, mAlphaCoalesce (true) -, mDigitCoalesce (true) -, mQuotedCoalesce (false) -, mWhiteCoalesce (false) -, mSkipWhitespace (false) -{ -} - -//////////////////////////////////////////////////////////////////////////////// -void Lexer::tokenize (std::vector & all) -{ - all.clear (); // Prevent repeated accumulation. - - std::string token; - bool inQuote = false; - char quoteChar = '\0'; - for (unsigned int i = 0; i < mInput.length (); ++i) - { - bool specialFound = false; - for (unsigned int s = 0; s < mSpecialTokens.size (); ++s) - { - std::string potential = mInput.substr ( - i, min (mSpecialTokens[s].length (), mInput.length () - i)); - - if (potential == mSpecialTokens[s]) - { - // Capture currently assembled token, the special token, increment over - // that token, and skip all remaining code in the loop. - if (token.length ()) - { - all.push_back (token); - token = ""; - } - - all.push_back (potential); - i += potential.length () - 1; - specialFound = true; - } - } - - if (specialFound) - continue; - - char c = mInput[i]; - char next = '\0'; - if (i < mInput.length () - 1) - next = mInput[i + 1]; - - // Classify current and next characters. - int thisChar = classify (c); - int nextChar = classify (next); - - // Properly set inQuote, quoteChar. - if (!inQuote && thisChar == quote) - { - quoteChar = c; - inQuote = true; - } - else if (inQuote && c == quoteChar) - { - inQuote = false; - } - - // Detect transitions. - bool transition = false; - if (thisChar != nextChar) - transition = true; - - token += c; - - // Transitions mean new token. All 'other' characters are separate tokens. - if (transition || nextChar == other) - { - if (!inQuote || !mQuotedCoalesce) - { - if (!mSkipWhitespace || thisChar != white) - all.push_back (token); - token = ""; - } - } - - // Non-transitions - runs. - else - { - // Runs may be optionally coalesced. - if (!(mAlphaCoalesce && nextChar == alpha) && - !(mDigitCoalesce && nextChar == digit) && - !(mWhiteCoalesce && nextChar == white)) - { - if (!inQuote || !mQuotedCoalesce) - { - if (!mSkipWhitespace || thisChar != white) - all.push_back (token); - token = ""; - } - } - } - } -} - -//////////////////////////////////////////////////////////////////////////////// -void Lexer::categorizeAsAlpha (char value) -{ - if (mAlpha.find (value) == std::string::npos) - mAlpha += value; - - std::string::size_type pos; - if ((pos = mDigit.find (value)) != std::string::npos) mDigit.erase (pos, 1); - if ((pos = mQuote.find (value)) != std::string::npos) mQuote.erase (pos, 1); - if ((pos = mWhite.find (value)) != std::string::npos) mWhite.erase (pos, 1); -} - -//////////////////////////////////////////////////////////////////////////////// -void Lexer::ignoreAsAlpha (char value) -{ - std::string::size_type pos; - if ((pos = mAlpha.find (value)) != std::string::npos) mAlpha.erase (pos, 1); -} - -//////////////////////////////////////////////////////////////////////////////// -void Lexer::setAlpha (const std::string& value) -{ - mAlpha = value; - - std::string::size_type pos; - for (unsigned int i = 0; i < mAlpha.length (); ++i) - { - if ((pos = mDigit.find (mAlpha[i])) != std::string::npos) mDigit.erase (pos, 1); - if ((pos = mQuote.find (mAlpha[i])) != std::string::npos) mQuote.erase (pos, 1); - if ((pos = mWhite.find (mAlpha[i])) != std::string::npos) mWhite.erase (pos, 1); - } -} - -//////////////////////////////////////////////////////////////////////////////// -void Lexer::categorizeAsDigit (char value) -{ - if (mDigit.find (value) == std::string::npos) - mDigit += value; - - std::string::size_type pos; - if ((pos = mAlpha.find (value)) != std::string::npos) mAlpha.erase (pos, 1); - if ((pos = mQuote.find (value)) != std::string::npos) mQuote.erase (pos, 1); - if ((pos = mWhite.find (value)) != std::string::npos) mWhite.erase (pos, 1); -} - -//////////////////////////////////////////////////////////////////////////////// -void Lexer::ignoreAsDigit (char value) -{ - std::string::size_type pos; - if ((pos = mDigit.find (value)) != std::string::npos) mDigit.erase (pos, 1); -} - -//////////////////////////////////////////////////////////////////////////////// -void Lexer::setDigit (const std::string& value) -{ - mDigit = value; - - std::string::size_type pos; - for (unsigned int i = 0; i < mDigit.length (); ++i) - { - if ((pos = mAlpha.find (mDigit[i])) != std::string::npos) mAlpha.erase (pos, 1); - if ((pos = mQuote.find (mDigit[i])) != std::string::npos) mQuote.erase (pos, 1); - if ((pos = mWhite.find (mDigit[i])) != std::string::npos) mWhite.erase (pos, 1); - } -} - -//////////////////////////////////////////////////////////////////////////////// -void Lexer::categorizeAsQuote (char value) -{ - if (mQuote.find (value) == std::string::npos) - mQuote += value; - - std::string::size_type pos; - if ((pos = mAlpha.find (value)) != std::string::npos) mAlpha.erase (pos, 1); - if ((pos = mDigit.find (value)) != std::string::npos) mDigit.erase (pos, 1); - if ((pos = mWhite.find (value)) != std::string::npos) mWhite.erase (pos, 1); -} - -//////////////////////////////////////////////////////////////////////////////// -void Lexer::ignoreAsQuote (char value) -{ - std::string::size_type pos; - if ((pos = mQuote.find (value)) != std::string::npos) mQuote.erase (pos, 1); -} - -//////////////////////////////////////////////////////////////////////////////// -void Lexer::setQuote (const std::string& value) -{ - mQuote = value; - - std::string::size_type pos; - for (unsigned int i = 0; i < mQuote.length (); ++i) - { - if ((pos = mAlpha.find (mQuote[i])) != std::string::npos) mAlpha.erase (pos, 1); - if ((pos = mDigit.find (mQuote[i])) != std::string::npos) mDigit.erase (pos, 1); - if ((pos = mWhite.find (mQuote[i])) != std::string::npos) mWhite.erase (pos, 1); - } -} - -//////////////////////////////////////////////////////////////////////////////// -void Lexer::categorizeAsWhite (char value) -{ - if (mWhite.find (value) == std::string::npos) - mWhite += value; - - std::string::size_type pos; - if ((pos = mAlpha.find (value)) != std::string::npos) mAlpha.erase (pos, 1); - if ((pos = mDigit.find (value)) != std::string::npos) mDigit.erase (pos, 1); - if ((pos = mQuote.find (value)) != std::string::npos) mQuote.erase (pos, 1); -} - -//////////////////////////////////////////////////////////////////////////////// -void Lexer::ignoreAsWhite (char value) -{ - std::string::size_type pos; - if ((pos = mWhite.find (value)) != std::string::npos) mWhite.erase (pos, 1); -} - -//////////////////////////////////////////////////////////////////////////////// -void Lexer::setWhite (const std::string& value) -{ - mWhite = value; - - std::string::size_type pos; - for (unsigned int i = 0; i < mWhite.length (); ++i) - { - if ((pos = mAlpha.find (mWhite[i])) != std::string::npos) mAlpha.erase (pos, 1); - if ((pos = mDigit.find (mWhite[i])) != std::string::npos) mDigit.erase (pos, 1); - if ((pos = mQuote.find (mWhite[i])) != std::string::npos) mQuote.erase (pos, 1); - } -} - -//////////////////////////////////////////////////////////////////////////////// -void Lexer::coalesceAlpha (bool value) -{ - mAlphaCoalesce = value; -} - -//////////////////////////////////////////////////////////////////////////////// -void Lexer::coalesceDigits (bool value) -{ - mDigitCoalesce = value; -} - -//////////////////////////////////////////////////////////////////////////////// -void Lexer::coalesceQuoted (bool value) -{ - mQuotedCoalesce = value; -} - -//////////////////////////////////////////////////////////////////////////////// -void Lexer::coalesceWhite (bool value) -{ - mWhiteCoalesce = value; -} - -//////////////////////////////////////////////////////////////////////////////// -void Lexer::skipWhitespace (bool value) -{ - mSkipWhitespace = value; -} - -//////////////////////////////////////////////////////////////////////////////// -void Lexer::specialToken (const std::string& special) -{ - mSpecialTokens.push_back (special); -} - -//////////////////////////////////////////////////////////////////////////////// -int Lexer::classify (char c) -{ - if (mAlpha.find (c) != std::string::npos) return alpha; - if (mDigit.find (c) != std::string::npos) return digit; - if (mWhite.find (c) != std::string::npos) return white; - if (mQuote.find (c) != std::string::npos) return quote; - - return other; -} - -//////////////////////////////////////////////////////////////////////////////// - diff --git a/src/Lexer.h b/src/Lexer.h deleted file mode 100644 index 62d529909..000000000 --- a/src/Lexer.h +++ /dev/null @@ -1,84 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// taskwarrior - a command line task list manager. -// -// Copyright 2011, Paul Beckingham, Federico Hernandez. -// All rights reserved. -// -// This program is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free Software -// Foundation; either version 2 of the License, or (at your option) any later -// version. -// -// This program is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more -// details. -// -// You should have received a copy of the GNU General Public License along with -// this program; if not, write to the -// -// Free Software Foundation, Inc., -// 51 Franklin Street, Fifth Floor, -// Boston, MA -// 02110-1301 -// USA -// -//////////////////////////////////////////////////////////////////////////////// - -#ifndef INCLUDED_LEXER -#define INCLUDED_LEXER - -#include -#include - -class Lexer -{ -public: - Lexer (const std::string&); - void tokenize (std::vector &); - - void categorizeAsAlpha (char); - void ignoreAsAlpha (char); - void setAlpha (const std::string&); - - void categorizeAsDigit (char); - void ignoreAsDigit (char); - void setDigit (const std::string&); - - void categorizeAsQuote (char); - void ignoreAsQuote (char); - void setQuote (const std::string&); - - void categorizeAsWhite (char); - void ignoreAsWhite (char); - void setWhite (const std::string&); - - void coalesceAlpha (bool); - void coalesceDigits (bool); - void coalesceQuoted (bool); - void coalesceWhite (bool); - void skipWhitespace (bool); - void specialToken (const std::string&); - -private: - int classify (char); - - std::string mInput; - - std::string mAlpha; - std::string mDigit; - std::string mQuote; - std::string mWhite; - - bool mAlphaCoalesce; - bool mDigitCoalesce; - bool mQuotedCoalesce; - bool mWhiteCoalesce; - bool mSkipWhitespace; - - std::vector mSpecialTokens; -}; - -#endif - -//////////////////////////////////////////////////////////////////////////////// diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index f3b21eaaa..3411ad024 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -6,11 +6,10 @@ include_directories (${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/test ${TASK_INCLUDE_DIRS}) -set (test_SRCS arguments.t att.t autocomplete.t color.t config.t date.t - directory.t dom.t duration.t file.t i18n.t json.t lexer.t list.t - nibbler.t path.t record.t rx.t t.benchmark.t t.t taskmod.t tdb.t - tdb2.t text.t uri.t util.t variant.t view.t - json_test) +set (test_SRCS att.t autocomplete.t color.t config.t date.t directory.t dom.t + duration.t file.t i18n.t json.t list.t nibbler.t path.t record.t + rx.t t.benchmark.t t.t taskmod.t tdb.t tdb2.t text.t uri.t util.t + variant.t view.t json_test) add_custom_target (test ./run_all DEPENDS ${test_SRCS} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/test) diff --git a/test/arguments.t.cpp b/test/arguments.t.cpp deleted file mode 100644 index ee4591287..000000000 --- a/test/arguments.t.cpp +++ /dev/null @@ -1,190 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// taskwarrior - a command line task list manager. -// -// Copyright 2006 - 2011, Paul Beckingham, Federico Hernandez. -// All rights reserved. -// -// This program is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free Software -// Foundation; either version 2 of the License, or (at your option) any later -// version. -// -// This program is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more -// details. -// -// You should have received a copy of the GNU General Public License along with -// this program; if not, write to the -// -// Free Software Foundation, Inc., -// 51 Franklin Street, Fifth Floor, -// Boston, MA -// 02110-1301 -// USA -// -//////////////////////////////////////////////////////////////////////////////// -#include -#include -#include -#include - -Context context; - -//////////////////////////////////////////////////////////////////////////////// -int main (int argc, char** argv) -{ - UnitTest t (95); - - const char* fake[] = - { - // task list proj:foo 1,3,5-10 12 pattern1 rc.name1=value1 rc.name2:value2 \ - // 234 -- pattern2 n:v - "task", // context.program - "list", // command - "proj:foo", // n:v - "1,3,5-10", // sequence - "12", // sequence - "pattern1", // text - "rc.name1=value1", // n:v - "rc.name2:value2", // n:v - "234", // text - "--", // terminator - "pattern2", // text - "n:v", // text (due to terminator) - }; - - // void capture (int, char**); - Arguments a1; - a1.capture (12, &fake[0]); - t.is (a1.size (), (size_t)12, "12 arguments expected"); - - // std::string combine (); - t.is (a1.combine (), - "task list proj:foo 1,3,5-10 12 pattern1 rc.name1=value1 rc.name2:value2 " - "234 -- pattern2 n:v", - "combine good"); - - // bool is_attr (const std::string&); - t.ok (Arguments::is_attr ("project:"), "name: -> attr"); - t.ok (Arguments::is_attr ("project:\"\""), "name:\"\" -> attr"); - t.ok (Arguments::is_attr ("project:one"), "name:one -> attr"); - t.ok (Arguments::is_attr ("project:\"one\""), "name:\"one\" -> attr"); - t.ok (Arguments::is_attr ("project:\"one two\""), "name:\"one two\" -> attr"); - - t.notok (Arguments::is_attr ("name"), "name -> not attr"); - t.notok (Arguments::is_attr ("(name=val and 1<2)"), "(name=val and 1<2) -> not attr"); - - // bool is_attmod (const std::string&); - t.ok (Arguments::is_attmod ("project.is:"), "name.is: -> attmod"); - t.ok (Arguments::is_attmod ("project.is:\"\""), "name.is:\"\" -> attmod"); - t.ok (Arguments::is_attmod ("project.is:one"), "name.is:one -> attmod"); - t.ok (Arguments::is_attmod ("project.is:\"one\""), "name.is:\"one\" -> attmod"); - t.ok (Arguments::is_attmod ("project.is:\"one two\""), "name.is:\"one two\" -> attmod"); - - t.notok (Arguments::is_attmod ("name"), "name -> not attmod"); - t.notok (Arguments::is_attmod ("(name=value and 1<2"), "(name=value and 1<2 -> not attmod"); - - // bool is_subst (const std::string&); - t.notok (Arguments::is_subst ("///"), "/// -> not subst"); - t.notok (Arguments::is_subst ("//to/"), "//to/ -> not subst"); - t.ok (Arguments::is_subst ("/from//"), "/from// -> subst"); - t.ok (Arguments::is_subst ("/from/to/"), "/from/to/ -> subst"); - t.ok (Arguments::is_subst ("/from from/to to/"), "/from from/to to/ -> subst"); - - t.notok (Arguments::is_subst ("///g"), "///g -> not subst"); - t.notok (Arguments::is_subst ("//to/g"), "//to/g -> not subst"); - t.ok (Arguments::is_subst ("/from//g"), "/from//g -> subst"); - t.ok (Arguments::is_subst ("/from/to/g"), "/from/to/g -> subst"); - t.ok (Arguments::is_subst ("/from from/to to/g"), "/from from/to to/g -> subst"); - - // bool is_pattern (const std::string&); - t.notok (Arguments::is_pattern ("//"), "// -> not pattern"); - t.notok (Arguments::is_pattern ("///"), "/// -> not pattern"); - t.ok (Arguments::is_pattern ("/one/"), "/one/ -> pattern"); - t.ok (Arguments::is_pattern ("/one two/"), "/one two/ -> pattern"); - t.ok (Arguments::is_pattern ("/ /"), "/ / -> pattern"); - - // bool is_id (const std::string&); - t.ok (Arguments::is_id ("1"), "1 -> id"); - t.ok (Arguments::is_id ("1,2"), "1,2 -> id"); - t.ok (Arguments::is_id ("1-2"), "1-2 -> id"); - t.ok (Arguments::is_id ("1,2,3"), "1,2,3 -> id"); - t.ok (Arguments::is_id ("1-2,3,4-5"), "1-2,3,4-5 -> id"); - t.notok (Arguments::is_id ("1-2-3"), "1-2-3 -> no id"); - - // bool is_uuid (const std::string&); - t.ok (Arguments::is_uuid ("00000000-0000-0000-0000-000000000000"), - "00000000-0000-0000-0000-000000000000 -> uuid"); - t.ok (Arguments::is_uuid ("eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,ffffffff-ffff-ffff-ffff-ffffffffffff"), - "eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,ffffffff-ffff-ffff-ffff-ffffffffffff -> uuid"); - - // bool is_tag (const std::string&); - t.ok (Arguments::is_tag ("+one"), "+one -> tag"); - t.ok (Arguments::is_tag ("-one"), "-one -> tag"); - t.notok (Arguments::is_tag ("+one "), "+one -> not tag"); - t.notok (Arguments::is_tag ("-one "), "-one -> not tag"); - t.notok (Arguments::is_tag ("+"), "+ -> not tag"); - t.notok (Arguments::is_tag ("-"), "- -> not tag"); - t.notok (Arguments::is_tag ("++"), "++ -> not tag"); - t.notok (Arguments::is_tag ("--"), "-- -> not tag"); - t.notok (Arguments::is_tag ("+one two"), "+one two -> not tag"); - - // bool is_operator (const std::string&); - t.ok (Arguments::is_operator ("!"), "! -> operator"); - t.ok (Arguments::is_operator ("-"), "- -> operator"); - t.ok (Arguments::is_operator ("*"), "* -> operator"); - t.ok (Arguments::is_operator ("/"), "/ -> operator"); - t.ok (Arguments::is_operator ("+"), "+ -> operator"); - t.ok (Arguments::is_operator ("-"), "- -> operator"); - t.ok (Arguments::is_operator ("<"), "< -> operator"); - t.ok (Arguments::is_operator ("<="), "<= -> operator"); - t.ok (Arguments::is_operator (">="), ">= -> operator"); - t.ok (Arguments::is_operator (">"), "> -> operator"); - t.ok (Arguments::is_operator ("~"), "~ -> operator"); - t.ok (Arguments::is_operator ("!~"), "!~ -> operator"); - t.ok (Arguments::is_operator ("="), "= -> operator"); - t.ok (Arguments::is_operator ("!="), "!= -> operator"); - t.ok (Arguments::is_operator ("and"), "and -> operator"); - t.ok (Arguments::is_operator ("xor"), "xor -> operator"); - t.ok (Arguments::is_operator ("or"), "or -> operator"); - t.ok (Arguments::is_operator ("("), "( -> operator"); - t.ok (Arguments::is_operator (")"), ") -> operator"); - t.notok (Arguments::is_operator ("$"), "$ -> not operator"); - - // bool is_expression (const std::string&); - t.notok (Arguments::is_expression ("foo"), "foo -> expression"); - t.ok (Arguments::is_expression ("1+1"), "1+1 -> expression"); - t.ok (Arguments::is_expression ("a~b"), "a~b -> expression"); - t.ok (Arguments::is_expression ("(1)"), "(1) -> expression"); - t.ok (Arguments::is_expression ("!a"), "!a -> expression"); - - // static bool valid_modifier (const std::string&); - t.ok (Arguments::valid_modifier ("before"), "before -> modifier"); - t.ok (Arguments::valid_modifier ("under"), "under -> modifier"); - t.ok (Arguments::valid_modifier ("below"), "below -> modifier"); - t.ok (Arguments::valid_modifier ("after"), "after -> modifier"); - t.ok (Arguments::valid_modifier ("over"), "over -> modifier"); - t.ok (Arguments::valid_modifier ("above"), "above -> modifier"); - t.ok (Arguments::valid_modifier ("none"), "none -> modifier"); - t.ok (Arguments::valid_modifier ("any"), "any -> modifier"); - t.ok (Arguments::valid_modifier ("is"), "is -> modifier"); - t.ok (Arguments::valid_modifier ("equals"), "equals -> modifier"); - t.ok (Arguments::valid_modifier ("isnt"), "isnt -> modifier"); - t.ok (Arguments::valid_modifier ("not"), "not -> modifier"); - t.ok (Arguments::valid_modifier ("has"), "has -> modifier"); - t.ok (Arguments::valid_modifier ("contains"), "contains -> modifier"); - t.ok (Arguments::valid_modifier ("hasnt"), "hasnt -> modifier"); - t.ok (Arguments::valid_modifier ("startswith"), "startswith -> modifier"); - t.ok (Arguments::valid_modifier ("left"), "left -> modifier"); - t.ok (Arguments::valid_modifier ("endswith"), "endswith -> modifier"); - t.ok (Arguments::valid_modifier ("right"), "right -> modifier"); - t.ok (Arguments::valid_modifier ("word"), "word -> modifier"); - t.ok (Arguments::valid_modifier ("noword"), "noword -> modifier"); - t.notok (Arguments::valid_modifier ("duck"), "duck -> not modified"); - - return 0; -} - -//////////////////////////////////////////////////////////////////////////////// - diff --git a/test/dom.t.cpp b/test/dom.t.cpp index 24f349a46..f0a2a7862 100644 --- a/test/dom.t.cpp +++ b/test/dom.t.cpp @@ -47,7 +47,7 @@ int main (int argc, char** argv) try { // Prime the pump. - context.args.capture ("task"); + context.a3.capture ("task"); // TODO dom.get rc.name DOM dom; diff --git a/test/lexer.t.cpp b/test/lexer.t.cpp deleted file mode 100644 index d4dd51c76..000000000 --- a/test/lexer.t.cpp +++ /dev/null @@ -1,331 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// taskwarrior - a command line task list manager. -// -// Copyright 2006 - 2011, Paul Beckingham. -// All rights reserved. -// -// This program is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free Software -// Foundation; either version 2 of the License, or (at your option) any later -// version. -// -// This program is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more -// details. -// -// You should have received a copy of the GNU General Public License along with -// this program; if not, write to the -// -// Free Software Foundation, Inc., -// 51 Franklin Street, Fifth Floor, -// Boston, MA -// 02110-1301 -// USA -// -//////////////////////////////////////////////////////////////////////////////// - -#include -#include -#include - -Context context; - -//////////////////////////////////////////////////////////////////////////////// -int main (int argc, char** argv) -{ - UnitTest t (80); - - std::string input = "This is a test."; - std::vector tokens; - { - Lexer l (input); - l.tokenize (tokens); - } - - t.is (tokens.size (), (size_t) 8, "'This is a test.' -> 'This| |is| |a| |test|.'"); - if (tokens.size () == 8) - { - t.is (tokens[0], "This", "'This is a test.' [0] -> 'This'"); - t.is (tokens[1], " ", "'This is a test.' [1] -> ' '"); - t.is (tokens[2], "is", "'This is a test.' [2] -> 'is'"); - t.is (tokens[3], " ", "'This is a test.' [3] -> ' '"); - t.is (tokens[4], "a", "'This is a test.' [4] -> 'a'"); - t.is (tokens[5], " ", "'This is a test.' [5] -> ' '"); - t.is (tokens[6], "test", "'This is a test.' [6] -> 'test'"); - t.is (tokens[7], ".", "'This is a test.' [7] -> '.'"); - } - else - { - t.skip ("'This is a test.' [0] -> 'This'"); - t.skip ("'This is a test.' [1] -> ' '"); - t.skip ("'This is a test.' [2] -> 'is'"); - t.skip ("'This is a test.' [3] -> ' '"); - t.skip ("'This is a test.' [4] -> 'a'"); - t.skip ("'This is a test.' [5] -> ' '"); - t.skip ("'This is a test.' [6] -> 'test'"); - t.skip ("'This is a test.' [7] -> '.'"); - } - - input = "a12bcd345efgh6789"; - { - Lexer l (input); - l.tokenize (tokens); - } - - t.is (tokens.size (), (size_t) 6, "'a12bcd345efgh6789' -> 'a|12|bcd|345|efgh|6789'"); - if (tokens.size () == 6) - { - t.is (tokens[0], "a", "'a12bcd345efgh6789' [0] -> 'a'"); - t.is (tokens[1], "12", "'a12bcd345efgh6789' [1] -> '12'"); - t.is (tokens[2], "bcd", "'a12bcd345efgh6789' [2] -> 'bcd'"); - t.is (tokens[3], "345", "'a12bcd345efgh6789' [3] -> '345'"); - t.is (tokens[4], "efgh", "'a12bcd345efgh6789' [4] -> 'efgh'"); - t.is (tokens[5], "6789", "'a12bcd345efgh6789' [5] -> '6789'"); - } - else - { - t.skip ("'a12bcd345efgh6789' [0] -> 'a'"); - t.skip ("'a12bcd345efgh6789' [1] -> '12'"); - t.skip ("'a12bcd345efgh6789' [2] -> 'bcd'"); - t.skip ("'a12bcd345efgh6789' [3] -> '345'"); - t.skip ("'a12bcd345efgh6789' [4] -> 'efgh'"); - t.skip ("'a12bcd345efgh6789' [5] -> '6789'"); - } - - // Let's throw some ugly Perl at it. - input = "my $variable_name = 'single string';"; - { - Lexer l (input); - l.categorizeAsAlpha ('_'); - l.coalesceQuoted (true); - l.tokenize (tokens); - } - - t.is (tokens.size (), (size_t) 9, "'my $variable_name = 'single string';' -> 'my| |$|variable_name| |=| |'|single string|'|;'"); - if (tokens.size () == 9) - { - t.is (tokens[0], "my", "'my $variable_name = 'single string';' [0] -> 'my'"); - t.is (tokens[1], " ", "'my $variable_name = 'single string';' [1] -> ' '"); - t.is (tokens[2], "$", "'my $variable_name = 'single string';' [2] -> '$'"); - t.is (tokens[3], "variable_name", "'my $variable_name = 'single string';' [3] -> 'variable_name'"); - t.is (tokens[4], " ", "'my $variable_name = 'single string';' [4] -> ' '"); - t.is (tokens[5], "=", "'my $variable_name = 'single string';' [5] -> '='"); - t.is (tokens[6], " ", "'my $variable_name = 'single string';' [6] -> ' '"); - t.is (tokens[7], "'single string'", "'my $variable_name = 'single string';' [8] -> ''single string''"); - t.is (tokens[8], ";", "'my $variable_name = 'single string';' [10] -> ';'"); - } - else - { - t.skip ("'my $variable_name = 'single string';' [0] -> 'my'"); - t.skip ("'my $variable_name = 'single string';' [1] -> ' '"); - t.skip ("'my $variable_name = 'single string';' [2] -> '$'"); - t.skip ("'my $variable_name = 'single string';' [3] -> 'variable_name'"); - t.skip ("'my $variable_name = 'single string';' [4] -> ' '"); - t.skip ("'my $variable_name = 'single string';' [5] -> '='"); - t.skip ("'my $variable_name = 'single string';' [6] -> ' '"); - t.skip ("'my $variable_name = 'single string';' [8] -> ''single string''"); - t.skip ("'my $variable_name = 'single string';' [10] -> ';'"); - } - - // Now exercise all the configurable coalescence. - input = "ab 12 'a'"; - { - Lexer l (input); - l.tokenize (tokens); - } - - t.is (tokens.size (), (size_t) 8, "'ab 12 'a'' -> 'ab| | |12| |'|a|''"); - if (tokens.size () == 8) - { - t.is (tokens[0], "ab", "'ab 12 'a'' [0] -> 'ab'"); - t.is (tokens[1], " ", "'ab 12 'a'' [1] -> ' '"); - t.is (tokens[2], " ", "'ab 12 'a'' [2] -> ' '"); - t.is (tokens[3], "12", "'ab 12 'a'' [3] -> '12'"); - t.is (tokens[4], " ", "'ab 12 'a'' [4] -> ' '"); - t.is (tokens[5], "'", "'ab 12 'a'' [5] -> '''"); - t.is (tokens[6], "a", "'ab 12 'a'' [6] -> 'a'"); - t.is (tokens[7], "'", "'ab 12 'a'' [7] -> '''"); - } - else - { - t.skip ("'ab 12 'a'' [0] -> 'ab'"); - t.skip ("'ab 12 'a'' [1] -> ' '"); - t.skip ("'ab 12 'a'' [2] -> ' '"); - t.skip ("'ab 12 'a'' [3] -> '12'"); - t.skip ("'ab 12 'a'' [4] -> ' '"); - t.skip ("'ab 12 'a'' [5] -> '''"); - t.skip ("'ab 12 'a'' [6] -> 'a'"); - t.skip ("'ab 12 'a'' [7] -> '''"); - } - - { - Lexer l (input); - l.coalesceAlpha (false); - l.tokenize (tokens); - } - - t.is (tokens.size (), (size_t) 9, "'ab 12 'a'' -> 'a|b| | |12| |'|a|''"); - if (tokens.size () == 9) - { - t.is (tokens[0], "a", "'ab 12 'a'' [0] -> 'a'"); - t.is (tokens[1], "b", "'ab 12 'a'' [1] -> 'b'"); - t.is (tokens[2], " ", "'ab 12 'a'' [2] -> ' '"); - t.is (tokens[3], " ", "'ab 12 'a'' [3] -> ' '"); - t.is (tokens[4], "12", "'ab 12 'a'' [4] -> '12'"); - t.is (tokens[5], " ", "'ab 12 'a'' [5] -> ' '"); - t.is (tokens[6], "'", "'ab 12 'a'' [6] -> '''"); - t.is (tokens[7], "a", "'ab 12 'a'' [7] -> 'a'"); - t.is (tokens[8], "'", "'ab 12 'a'' [8] -> '''"); - } - else - { - t.skip ("'ab 12 'a'' [0] -> 'a'"); - t.skip ("'ab 12 'a'' [1] -> 'b'"); - t.skip ("'ab 12 'a'' [2] -> ' '"); - t.skip ("'ab 12 'a'' [3] -> ' '"); - t.skip ("'ab 12 'a'' [4] -> '12'"); - t.skip ("'ab 12 'a'' [5] -> ' '"); - t.skip ("'ab 12 'a'' [6] -> '''"); - t.skip ("'ab 12 'a'' [7] -> 'a'"); - t.skip ("'ab 12 'a'' [8] -> '''"); - } - - { - Lexer l (input); - l.coalesceDigits (false); - l.tokenize (tokens); - } - - t.is (tokens.size (), (size_t) 9, "'ab 12 'a'' -> 'ab| | |1|2| |'|a|''"); - if (tokens.size () == 9) - { - t.is (tokens[0], "ab", "'ab 12 'a'' [0] -> 'ab'"); - t.is (tokens[1], " ", "'ab 12 'a'' [1] -> ' '"); - t.is (tokens[2], " ", "'ab 12 'a'' [2] -> ' '"); - t.is (tokens[3], "1", "'ab 12 'a'' [3] -> '1'"); - t.is (tokens[4], "2", "'ab 12 'a'' [4] -> '2'"); - t.is (tokens[5], " ", "'ab 12 'a'' [5] -> ' '"); - t.is (tokens[6], "'", "'ab 12 'a'' [6] -> '''"); - t.is (tokens[7], "a", "'ab 12 'a'' [7] -> 'a'"); - t.is (tokens[8], "'", "'ab 12 'a'' [8] -> '''"); - } - else - { - t.skip ("'ab 12 'a'' [0] -> 'ab'"); - t.skip ("'ab 12 'a'' [1] -> ' '"); - t.skip ("'ab 12 'a'' [2] -> ' '"); - t.skip ("'ab 12 'a'' [3] -> '1'"); - t.skip ("'ab 12 'a'' [4] -> '2'"); - t.skip ("'ab 12 'a'' [5] -> ' '"); - t.skip ("'ab 12 'a'' [6] -> '''"); - t.skip ("'ab 12 'a'' [7] -> 'a'"); - t.skip ("'ab 12 'a'' [8] -> '''"); - } - - { - Lexer l (input); - l.coalesceQuoted (true); - l.tokenize (tokens); - } - - t.is (tokens.size (), (size_t) 6, "'ab 12 'a'' -> 'ab| | |12| |'a''"); - if (tokens.size () == 6) - { - t.is (tokens[0], "ab", "'ab 12 'a'' [0] -> 'ab'"); - t.is (tokens[1], " ", "'ab 12 'a'' [1] -> ' '"); - t.is (tokens[2], " ", "'ab 12 'a'' [2] -> ' '"); - t.is (tokens[3], "12", "'ab 12 'a'' [3] -> '12'"); - t.is (tokens[4], " ", "'ab 12 'a'' [4] -> ' '"); - t.is (tokens[5], "'a'", "'ab 12 'a'' [5] -> ''a''"); - } - else - { - t.skip ("'ab 12 'a'' [0] -> 'ab'"); - t.skip ("'ab 12 'a'' [1] -> ' '"); - t.skip ("'ab 12 'a'' [2] -> ' '"); - t.skip ("'ab 12 'a'' [3] -> '12'"); - t.skip ("'ab 12 'a'' [4] -> ' '"); - t.skip ("'ab 12 'a'' [5] -> ''a''"); - } - - { - Lexer l (input); - l.coalesceWhite (true); - l.tokenize (tokens); - } - - t.is (tokens.size (), (size_t) 7, "'ab 12 'a'' -> 'ab| |12| |'|a|''"); - if (tokens.size () == 7) - { - t.is (tokens[0], "ab", "'ab 12 'a'' [0] -> 'ab'"); - t.is (tokens[1], " ", "'ab 12 'a'' [1] -> ' '"); - t.is (tokens[2], "12", "'ab 12 'a'' [2] -> '12'"); - t.is (tokens[3], " ", "'ab 12 'a'' [3] -> ' '"); - t.is (tokens[4], "'", "'ab 12 'a'' [4] -> '''"); - t.is (tokens[5], "a", "'ab 12 'a'' [5] -> 'a'"); - t.is (tokens[6], "'", "'ab 12 'a'' [6] -> '''"); - } - else - { - t.skip ("'ab 12 'a'' [0] -> 'ab'"); - t.skip ("'ab 12 'a'' [1] -> ' '"); - t.skip ("'ab 12 'a'' [2] -> '12'"); - t.skip ("'ab 12 'a'' [3] -> ' '"); - t.skip ("'ab 12 'a'' [4] -> '''"); - t.skip ("'ab 12 'a'' [5] -> 'a'"); - t.skip ("'ab 12 'a'' [6] -> '''"); - } - - { - Lexer l (input); - l.skipWhitespace (true); - l.tokenize (tokens); - } - - t.is (tokens.size (), (size_t) 5, "'ab 12 'a'' -> 'ab|12|'|a|''"); - if (tokens.size () == 5) - { - t.is (tokens[0], "ab", "'ab 12 'a'' [0] -> 'ab'"); - t.is (tokens[1], "12", "'ab 12 'a'' [1] -> '12'"); - t.is (tokens[2], "'", "'ab 12 'a'' [2] -> '''"); - t.is (tokens[3], "a", "'ab 12 'a'' [3] -> 'a'"); - t.is (tokens[4], "'", "'ab 12 'a'' [4] -> '''"); - } - else - { - t.skip ("'ab 12 'a'' [0] -> 'ab'"); - t.skip ("'ab 12 'a'' [1] -> '12'"); - t.skip ("'ab 12 'a'' [2] -> '''"); - t.skip ("'ab 12 'a'' [3] -> 'a'"); - t.skip ("'ab 12 'a'' [4] -> '''"); - } - - // Special tokens - input = "a := 1"; - { - Lexer l (input); - l.skipWhitespace (true); - l.specialToken (":="); - l.tokenize (tokens); - } - - t.is (tokens.size (), (size_t) 3, "'a := 1' -> 'a|:=|1'"); - if (tokens.size () == 3) - { - t.is (tokens[0], "a", "'a := 1' [0] -> 'a'"); - t.is (tokens[1], ":=", "'a := 1' [1] -> ':='"); - t.is (tokens[2], "1", "'a := 1' [2] -> '1'"); - } - else - { - t.skip ("'a := 1' [0] -> 'a'"); - t.skip ("'a := 1' [1] -> ':='"); - t.skip ("'a := 1' [2] -> '1'"); - } - - return 0; -} - -//////////////////////////////////////////////////////////////////////////////// -