From 0603711aaccd443cc63fe767aa016f760d82be5d Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Thu, 16 Oct 2014 00:37:48 -0400 Subject: [PATCH] CLI - Implemnted ::unsweetenAttMods. --- src/CLI.cpp | 173 +++++++++++++++++++++++++++++++++++++++++++++++++++- src/CLI.h | 1 + 2 files changed, 173 insertions(+), 1 deletion(-) diff --git a/src/CLI.cpp b/src/CLI.cpp index 1bce84ba2..c7e2959ac 100644 --- a/src/CLI.cpp +++ b/src/CLI.cpp @@ -293,7 +293,8 @@ const std::string CLI::getFilter () // Remove all the syntactic sugar. unsweetenTags (); unsweetenAtts (); - // TODO all the other types: att, attmod, pattern, id, uuid ... + unsweetenAttMods (); + // TODO all the other types: pattern, id, uuid ... std::string filter = ""; if (_args.size ()) @@ -630,6 +631,176 @@ void CLI::unsweetenAtts () _args = reconstructed; } +//////////////////////////////////////////////////////////////////////////////// +// .[:=]['"]['"] --> name value +void CLI::unsweetenAttMods () +{ + std::vector reconstructed; + std::vector ::iterator a; + for (a = _args.begin (); a != _args.end (); ++a) + { + // Look for a valid attribute name. + bool found = false; + Nibbler n (a->attribute ("raw")); + std::string name; + if (n.getUntil (".", name) && + name.length ()) + { + std::string canonical; + if (canonicalize (canonical, "attribute", name) || + canonicalize (canonical, "uda", name)) + { + if (n.skip ('.')) + { + std::string sense = "+"; + if (n.skip ('~')) + sense = "-"; + + std::string modifier; + n.getUntilOneOf (":=", modifier); + + if (n.skip (':') || + n.skip ('=')) + { + std::string value; + if (n.getQuoted ('"', value) || + n.getQuoted ('\'', value) || + n.getUntilEOS (value) || + n.depleted ()) + { + if (value == "") + value = "''"; + + A lhs ("argAttMod", name); + lhs.tag ("ATTMOD"); + lhs.tag ("FILTER"); + + lhs.attribute ("name", canonical); + lhs.attribute ("raw", value); + lhs.attribute ("modifier", modifier); + lhs.attribute ("sense", sense); + + std::map ::const_iterator col; + col = context.columns.find (canonical); + if (col != context.columns.end () && + col->second->modifiable ()) + { + lhs.tag ("MODIFIABLE"); + } + + A op ("argAttmod", ""); + op.tag ("FILTER"); + + A rhs ("argAttMod", ""); + rhs.tag ("FILTER"); + + if (modifier == "before" || modifier == "under" || modifier == "below") + { + op.attribute ("raw", "<"); + op.tag ("OP"); + rhs.attribute ("raw", value); + } + else if (modifier == "after" || modifier == "over" || modifier == "above") + { + op.attribute ("raw", ">"); + op.tag ("OP"); + rhs.attribute ("raw", value); + } + else if (modifier == "none") + { + op.attribute ("raw", "=="); + op.tag ("OP"); + rhs.attribute ("raw", "''"); + } + else if (modifier == "any") + { + op.attribute ("raw", "!="); + op.tag ("OP"); + rhs.attribute ("raw", "''"); + } + else if (modifier == "is" || modifier == "equals") + { + op.attribute ("raw", "=="); + op.tag ("OP"); + rhs.attribute ("raw", value); + } + else if (modifier == "isnt" || modifier == "not") + { + op.attribute ("raw", "!="); + op.tag ("OP"); + rhs.attribute ("raw", value); + } + else if (modifier == "has" || modifier == "contains") + { + op.attribute ("raw", "~"); + op.tag ("OP"); + rhs.attribute ("raw", value); + } + else if (modifier == "hasnt") + { + op.attribute ("raw", "!~"); + op.tag ("OP"); + rhs.attribute ("raw", value); + } + else if (modifier == "startswith" || modifier == "left") + { + op.attribute ("raw", "~"); + op.tag ("OP"); + rhs.attribute ("raw", "'^" + value + "'"); + } + else if (modifier == "endswith" || modifier == "right") + { + op.attribute ("raw", "~"); + op.tag ("OP"); + rhs.attribute ("raw", "'" + value + "$'"); + } + else if (modifier == "word") + { + op.attribute ("raw", "~"); + op.tag ("OP"); + + +#if defined (DARWIN) + rhs.attribute ("raw", value); +#elif defined (SOLARIS) + rhs.attribute ("raw", "'\\<" + value + "\\>'"); +#else + rhs.attribute ("raw", "'\\b" + value + "\\b'"); +#endif + } + else if (modifier == "noword") + { + op.attribute ("raw", "!~"); + op.tag ("OP"); + +#if defined (DARWIN) + rhs.attribute ("raw", value); +#elif defined (SOLARIS) + rhs.attribute ("raw", "'\\<" + value + "\\>'"); +#else + rhs.attribute ("raw", "'\\b" + value + "\\b'"); +#endif + } + else + throw format (STRING_PARSER_UNKNOWN_ATTMOD, modifier); + + reconstructed.push_back (lhs); + reconstructed.push_back (op); + reconstructed.push_back (rhs); + found = true; + } + } + } + } + } + + if (!found) + reconstructed.push_back (*a); + } + + _args = reconstructed; +} + //////////////////////////////////////////////////////////////////////////////// void CLI::dump (const std::string& label) const { diff --git a/src/CLI.h b/src/CLI.h index 0d8bebcca..d8f254641 100644 --- a/src/CLI.h +++ b/src/CLI.h @@ -78,6 +78,7 @@ private: bool canonicalize (std::string&, const std::string&, const std::string&) const; void unsweetenTags (); void unsweetenAtts (); + void unsweetenAttMods (); void dump (const std::string&) const; public: