CLI2: Refactoring

- Whenever A2::attribute sees 'raw' being set, it automaticall decomposes the
  arg, which can now be removed from other methods.
- New ::canonicalizeNames method means that the ::decomposeMod* methods are no
  longer needed.
- Removed ::findOverrides which now does nothing.
This commit is contained in:
Paul Beckingham 2015-07-05 16:13:56 -04:00
parent b46bf15f40
commit 460f2aeea5
2 changed files with 84 additions and 30 deletions

View file

@ -110,6 +110,9 @@ void A2::unTag (const std::string& tag)
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; _attributes[name] = value;
if (name == "raw")
decompose ();
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -117,6 +120,9 @@ void A2::attribute (const std::string& name, const std::string& value)
void A2::attribute (const std::string& name, const int value) void A2::attribute (const std::string& name, const int value)
{ {
_attributes[name] = format (value); _attributes[name] = format (value);
if (name == "raw")
decompose ();
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -141,6 +147,64 @@ const std::string A2::getToken () const
return i->second; return i->second;
} }
////////////////////////////////////////////////////////////////////////////////
void A2::decompose ()
{
if (_lextype == Lexer::Type::tag)
{
std::string raw = _attributes["raw"];
attribute ("name", raw.substr (1));
attribute ("sign", raw.substr (0, 1));
}
else if (_lextype == Lexer::Type::substitution)
{
std::string raw = _attributes["raw"];
auto slash1 = raw.find ("/");
auto slash2 = raw.find ("/", slash1 + 1);
auto slash3 = raw.find ("/", slash2 + 1);
attribute ("from", raw.substr (slash1 + 1, slash2 - slash1 - 1));
attribute ("to", raw.substr (slash2 + 1, slash3 - slash2 - 1));
attribute ("global", raw.substr (slash3 + 1) == "g" ? 1 : 0);
}
else if (_lextype == Lexer::Type::pair)
{
std::string raw = _attributes["raw"];
// TODO name:value --> canonical="name" value="value"
// TODO name=value --> canonical="name" value="value"
// TODO name:=value --> canonical="name" value="value"
// TODO name::value --> canonical="name" value="value"
// TODO name.mod:value -->
// TODO name.mod=value -->
// TODO name.mod:=value -->
// TODO name.mod::value -->
auto colon = raw.find (':');
auto equal = raw.find ('=');
// Q: Which of ':', '=' is the separator?
// A: Whichever comes first. For example:
// name:a=b
// name=a:b
// Both are valid, and 'name' is the attribute name in each case.
std::string::size_type separator = std::min (colon, equal);
std::string name = raw.substr (0, separator);
std::string value = raw.substr (separator + 1);
attribute ("name", name);
attribute ("value", value);
if (raw.substr (0, 3) == "rc:")
tag ("RC");
if (raw.substr (0, 3) == "rc.")
tag ("CONFIG");
}
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
const std::string A2::dump () const const std::string A2::dump () const
{ {
@ -433,7 +497,6 @@ void CLI2::analyze ()
// Process _args. // Process _args.
aliasExpansion (); aliasExpansion ();
findOverrides ();
if (! findCommand ()) if (! findCommand ())
{ {
defaultCommand (); defaultCommand ();
@ -441,6 +504,8 @@ void CLI2::analyze ()
throw std::string (STRING_TRIVIAL_INPUT); throw std::string (STRING_TRIVIAL_INPUT);
} }
canonicalizeNames ();
if (context.config.getInteger ("debug.parser") >= 3) if (context.config.getInteger ("debug.parser") >= 3)
context.debug (dump ("CLI2::analyze end")); context.debug (dump ("CLI2::analyze end"));
} }
@ -573,9 +638,9 @@ void CLI2::prepareFilter (bool applyContext)
insertJunctions (); // Deliberately after all desugar calls. insertJunctions (); // Deliberately after all desugar calls.
// Decompose the elements for MODIFICATIONs. // Decompose the elements for MODIFICATIONs.
decomposeModAttributes (); //decomposeModAttributes ();
decomposeModTags (); //decomposeModTags ();
decomposeModSubstitutions (); //decomposeModSubstitutions ();
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -811,34 +876,21 @@ void CLI2::aliasExpansion ()
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Scan all arguments that begin with either "rc:" or "rc.", extract the // Scan all arguments and canonicalize names that need it.
// name/values. void CLI2::canonicalizeNames ()
void CLI2::findOverrides ()
{ {
bool changes = false; bool changes = false;
std::string raw;
for (auto& a : _args) for (auto& a : _args)
{ {
raw = a.attribute ("raw"); if (a._lextype == Lexer::Type::pair)
if (raw.length () > 3 &&
raw.find ("rc:") == 0)
{ {
a.tag ("RC"); std::string name = a.attribute ("name");
a.attribute ("file", raw.substr (3)); std::string canonical;
changes = true; if (canonicalize (canonical, "pseudo", name) ||
} canonicalize (canonical, "attribute", name) ||
else if (raw.length () > 3 && canonicalize (canonical, "uda", name))
raw.find ("rc.") == 0)
{ {
auto sep = raw.find ('=', 3); a.attribute ("canonical", canonical);
if (sep == std::string::npos)
sep = raw.find (':', 3);
if (sep != std::string::npos)
{
a.tag ("CONFIG");
a.attribute ("name", raw.substr (3, sep - 3));
a.attribute ("value", raw.substr (sep + 1));
changes = true; changes = true;
} }
} }
@ -846,7 +898,7 @@ void CLI2::findOverrides ()
if (changes && if (changes &&
context.config.getInteger ("debug.parser") >= 3) context.config.getInteger ("debug.parser") >= 3)
context.debug (dump ("CLI2::analyze findOverrides")); context.debug (dump ("CLI2::analyze canonicalizeNames"));
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -1459,8 +1511,7 @@ void CLI2::insertIDExpr ()
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// TODO Removed because this algorithm is unreliable. // TODO Removed because this algorithm is unreliable. Fix it.
void CLI2::desugarFilterPlainArgs () void CLI2::desugarFilterPlainArgs ()
{ {
/* /*

View file

@ -49,6 +49,9 @@ public:
const std::string getToken () const; const std::string getToken () const;
const std::string dump () const; const std::string dump () const;
private:
void decompose ();
public: public:
Lexer::Type _lextype; Lexer::Type _lextype;
std::vector <std::string> _tags; std::vector <std::string> _tags;
@ -88,7 +91,7 @@ private:
void lexArguments (); void lexArguments ();
void demoteDOM (); void demoteDOM ();
void aliasExpansion (); void aliasExpansion ();
void findOverrides (); void canonicalizeNames ();
bool findCommand (); bool findCommand ();
bool exactMatch (const std::string&, const std::string&) const; bool exactMatch (const std::string&, const std::string&) const;
void desugarFilterTags (); void desugarFilterTags ();