mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-06-26 10:54:26 +02:00
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:
parent
b46bf15f40
commit
460f2aeea5
2 changed files with 84 additions and 30 deletions
109
src/CLI2.cpp
109
src/CLI2.cpp
|
@ -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 ()
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -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 ();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue