CLI
- Renamed ::desugarIDs to ::findIDs, as it is now a passive method. - Renamed ::desugarUUIDs to ::findUUIDs, as it is now a passive method. - Added ::insertIDExpr which creates one ID/UUID clause from the harvested ID and UUID values.
This commit is contained in:
302
src/CLI.cpp
302
src/CLI.cpp
@@ -251,6 +251,9 @@ void CLI::initialize (int argc, const char** argv)
|
|||||||
{
|
{
|
||||||
// Clean what needs to be cleaned. Everything in this case.
|
// Clean what needs to be cleaned. Everything in this case.
|
||||||
_original_args.clear ();
|
_original_args.clear ();
|
||||||
|
_id_ranges.clear ();
|
||||||
|
_uuid_list.clear ();
|
||||||
|
|
||||||
for (int i = 0; i < argc; ++i)
|
for (int i = 0; i < argc; ++i)
|
||||||
_original_args.push_back (argv[i]);
|
_original_args.push_back (argv[i]);
|
||||||
|
|
||||||
@@ -275,6 +278,8 @@ void CLI::analyze (bool parse /* = true */)
|
|||||||
{
|
{
|
||||||
// Clean what needs to be cleaned. Most in this case.
|
// Clean what needs to be cleaned. Most in this case.
|
||||||
_args.clear ();
|
_args.clear ();
|
||||||
|
_id_ranges.clear ();
|
||||||
|
_uuid_list.clear ();
|
||||||
|
|
||||||
for (int i = 0; i < _original_args.size (); ++i)
|
for (int i = 0; i < _original_args.size (); ++i)
|
||||||
{
|
{
|
||||||
@@ -318,8 +323,9 @@ void CLI::analyze (bool parse /* = true */)
|
|||||||
desugarAttributes ();
|
desugarAttributes ();
|
||||||
desugarAttributeModifiers ();
|
desugarAttributeModifiers ();
|
||||||
desugarPatterns ();
|
desugarPatterns ();
|
||||||
desugarIDs ();
|
findIDs ();
|
||||||
desugarUUIDs ();
|
findUUIDs ();
|
||||||
|
insertIDExpr ();
|
||||||
findOperators ();
|
findOperators ();
|
||||||
insertJunctions ();
|
insertJunctions ();
|
||||||
desugarPlainArgs ();
|
desugarPlainArgs ();
|
||||||
@@ -995,9 +1001,8 @@ void CLI::desugarPatterns ()
|
|||||||
// a range: 5-10
|
// a range: 5-10
|
||||||
// or a combination: 1,3,5-10 12
|
// or a combination: 1,3,5-10 12
|
||||||
//
|
//
|
||||||
void CLI::desugarIDs ()
|
void CLI::findIDs ()
|
||||||
{
|
{
|
||||||
std::vector <A> reconstructed;
|
|
||||||
std::vector <A>::iterator a;
|
std::vector <A>::iterator a;
|
||||||
for (a = _args.begin (); a != _args.end (); ++a)
|
for (a = _args.begin (); a != _args.end (); ++a)
|
||||||
{
|
{
|
||||||
@@ -1016,7 +1021,7 @@ void CLI::desugarIDs ()
|
|||||||
std::vector <std::string> elements;
|
std::vector <std::string> elements;
|
||||||
split (elements, raw, ',');
|
split (elements, raw, ',');
|
||||||
|
|
||||||
bool not_an_id = false;
|
bool is_an_id = true;
|
||||||
std::vector <std::string>::iterator e;
|
std::vector <std::string>::iterator e;
|
||||||
for (e = elements.begin (); e != elements.end (); ++e)
|
for (e = elements.begin (); e != elements.end (); ++e)
|
||||||
{
|
{
|
||||||
@@ -1028,7 +1033,7 @@ void CLI::desugarIDs ()
|
|||||||
{
|
{
|
||||||
if (! digitsOnly (terms[0]))
|
if (! digitsOnly (terms[0]))
|
||||||
{
|
{
|
||||||
not_an_id = true;
|
is_an_id = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1041,7 +1046,7 @@ void CLI::desugarIDs ()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
not_an_id = true;
|
is_an_id = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1050,7 +1055,7 @@ void CLI::desugarIDs ()
|
|||||||
if (! digitsOnly (terms[0]) ||
|
if (! digitsOnly (terms[0]) ||
|
||||||
! digitsOnly (terms[1]))
|
! digitsOnly (terms[1]))
|
||||||
{
|
{
|
||||||
not_an_id = true;
|
is_an_id = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1070,135 +1075,39 @@ void CLI::desugarIDs ()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
not_an_id = true;
|
is_an_id = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
not_an_id = true;
|
is_an_id = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! not_an_id)
|
if (is_an_id)
|
||||||
{
|
{
|
||||||
// Now convert the ranges into an infix expression.
|
a->tag ("ID");
|
||||||
A openParen ("argSeq", "(");
|
|
||||||
openParen.tag ("FILTER");
|
|
||||||
openParen.tag ("OP");
|
|
||||||
reconstructed.push_back (openParen);
|
|
||||||
|
|
||||||
|
// Save the ranges.
|
||||||
std::vector <std::pair <int, int> >::iterator r;
|
std::vector <std::pair <int, int> >::iterator r;
|
||||||
for (r = ranges.begin (); r != ranges.end (); ++r)
|
for (r = ranges.begin (); r != ranges.end (); ++r)
|
||||||
{
|
_id_ranges.push_back (*r);
|
||||||
if (r != ranges.begin ())
|
|
||||||
{
|
|
||||||
A opOp ("argSeq", "or");
|
|
||||||
opOp.tag ("FILTER");
|
|
||||||
opOp.tag ("OP");
|
|
||||||
reconstructed.push_back (opOp);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (r->first == r->second)
|
|
||||||
{
|
|
||||||
A id ("argSeq", "id");
|
|
||||||
id.tag ("FILTER");
|
|
||||||
id.tag ("ATTRIBUTE");
|
|
||||||
reconstructed.push_back (id);
|
|
||||||
|
|
||||||
A equal ("argSeq", "==");
|
|
||||||
equal.tag ("FILTER");
|
|
||||||
equal.tag ("OP");
|
|
||||||
reconstructed.push_back (equal);
|
|
||||||
|
|
||||||
A value ("argSeq", r->first);
|
|
||||||
value.tag ("FILTER");
|
|
||||||
value.tag ("LITERAL");
|
|
||||||
value.tag ("NUMBER");
|
|
||||||
reconstructed.push_back (value);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
A rangeOpenParen ("argSeq", "(");
|
|
||||||
rangeOpenParen.tag ("FILTER");
|
|
||||||
rangeOpenParen.tag ("OP");
|
|
||||||
reconstructed.push_back (rangeOpenParen);
|
|
||||||
|
|
||||||
A startId ("argSeq", "id");
|
|
||||||
startId.tag ("FILTER");
|
|
||||||
startId.tag ("ATTRIBUTE");
|
|
||||||
reconstructed.push_back (startId);
|
|
||||||
|
|
||||||
A gte ("argSeq", ">=");
|
|
||||||
gte.tag ("FILTER");
|
|
||||||
gte.tag ("OP");
|
|
||||||
reconstructed.push_back (gte);
|
|
||||||
|
|
||||||
A startValue ("argSeq", r->first);
|
|
||||||
startValue.tag ("FILTER");
|
|
||||||
startValue.tag ("LITERAL");
|
|
||||||
startValue.tag ("NUMBER");
|
|
||||||
reconstructed.push_back (startValue);
|
|
||||||
|
|
||||||
A andOp ("argSeq", "and");
|
|
||||||
andOp.tag ("FILTER");
|
|
||||||
andOp.tag ("OP");
|
|
||||||
reconstructed.push_back (andOp);
|
|
||||||
|
|
||||||
A endId ("argSeq", "id");
|
|
||||||
endId.tag ("FILTER");
|
|
||||||
endId.tag ("ATTRIBUTE");
|
|
||||||
reconstructed.push_back (endId);
|
|
||||||
|
|
||||||
A lte ("argSeq", "<=");
|
|
||||||
lte.tag ("FILTER");
|
|
||||||
lte.tag ("OP");
|
|
||||||
reconstructed.push_back (lte);
|
|
||||||
|
|
||||||
A endValue ("argSeq", r->second);
|
|
||||||
endValue.tag ("FILTER");
|
|
||||||
endValue.tag ("LITERAL");
|
|
||||||
endValue.tag ("NUMBER");
|
|
||||||
reconstructed.push_back (endValue);
|
|
||||||
|
|
||||||
A rangeCloseParen ("argSeq", ")");
|
|
||||||
rangeCloseParen.tag ("FILTER");
|
|
||||||
rangeCloseParen.tag ("OP");
|
|
||||||
reconstructed.push_back (rangeCloseParen);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
A closeParen ("argSeq", ")");
|
|
||||||
closeParen.tag ("FILTER");
|
|
||||||
closeParen.tag ("OP");
|
|
||||||
reconstructed.push_back (closeParen);
|
|
||||||
|
|
||||||
found = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!found)
|
|
||||||
reconstructed.push_back (*a);
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
reconstructed.push_back (*a);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_args = reconstructed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void CLI::desugarUUIDs ()
|
void CLI::findUUIDs ()
|
||||||
{
|
{
|
||||||
std::vector <A> reconstructed;
|
|
||||||
std::vector <A>::iterator a;
|
std::vector <A>::iterator a;
|
||||||
for (a = _args.begin (); a != _args.end (); ++a)
|
for (a = _args.begin (); a != _args.end (); ++a)
|
||||||
{
|
{
|
||||||
if (a->hasTag ("FILTER"))
|
if (a->hasTag ("FILTER"))
|
||||||
{
|
{
|
||||||
bool found = false;
|
|
||||||
|
|
||||||
// UUIDs have a limited character set.
|
// UUIDs have a limited character set.
|
||||||
std::string raw = a->attribute ("raw");
|
std::string raw = a->attribute ("raw");
|
||||||
if (raw.find_first_not_of ("0123456789abcdefABCDEF-,") == std::string::npos)
|
if (raw.find_first_not_of ("0123456789abcdefABCDEF-,") == std::string::npos)
|
||||||
@@ -1222,51 +1131,140 @@ void CLI::desugarUUIDs ()
|
|||||||
|
|
||||||
if (n.depleted ())
|
if (n.depleted ())
|
||||||
{
|
{
|
||||||
A openParen ("argSeq", "(");
|
_uuid_list = uuidList;
|
||||||
openParen.tag ("FILTER");
|
a->tag ("UUID");
|
||||||
openParen.tag ("OP");
|
|
||||||
reconstructed.push_back (openParen);
|
|
||||||
|
|
||||||
std::vector <std::string>::iterator u;
|
|
||||||
for (u = uuidList.begin (); u != uuidList.end (); ++u)
|
|
||||||
{
|
|
||||||
if (u != uuidList.begin ())
|
|
||||||
{
|
|
||||||
A openParen ("argSeq", "or");
|
|
||||||
openParen.tag ("FILTER");
|
|
||||||
openParen.tag ("OP");
|
|
||||||
reconstructed.push_back (openParen);
|
|
||||||
}
|
|
||||||
|
|
||||||
A uuid ("argSeq", "uuid");
|
|
||||||
uuid.tag ("FILTER");
|
|
||||||
uuid.tag ("ATTRIBUTE");
|
|
||||||
reconstructed.push_back (uuid);
|
|
||||||
|
|
||||||
A equal ("argSeq", "=");
|
|
||||||
equal.tag ("FILTER");
|
|
||||||
equal.tag ("OP");
|
|
||||||
reconstructed.push_back (equal);
|
|
||||||
|
|
||||||
A value ("argSeq", "'" + *u + "'");
|
|
||||||
value.tag ("FILTER");
|
|
||||||
value.tag ("LITERAL");
|
|
||||||
value.tag ("STRING");
|
|
||||||
reconstructed.push_back (value);
|
|
||||||
}
|
|
||||||
|
|
||||||
A closeParen ("argSeq", ")");
|
|
||||||
closeParen.tag ("FILTER");
|
|
||||||
closeParen.tag ("OP");
|
|
||||||
reconstructed.push_back (closeParen);
|
|
||||||
|
|
||||||
found = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!found)
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
reconstructed.push_back (*a);
|
void CLI::insertIDExpr ()
|
||||||
|
{
|
||||||
|
// Iterate over all args. The first ID/UUID arg found will be replaced by
|
||||||
|
// the combined ID clause. All other ID/UUID args are removed.
|
||||||
|
bool foundID = false;
|
||||||
|
std::vector <A> reconstructed;
|
||||||
|
std::vector <A>::iterator a;
|
||||||
|
for (a = _args.begin (); a != _args.end (); ++a)
|
||||||
|
{
|
||||||
|
if (a->hasTag ("FILTER") &&
|
||||||
|
(a->hasTag ("ID") ||
|
||||||
|
a->hasTag ("UUID")))
|
||||||
|
{
|
||||||
|
if (! foundID)
|
||||||
|
{
|
||||||
|
foundID = true;
|
||||||
|
|
||||||
|
// Construct a single sequence that represents all _id_ranges and
|
||||||
|
// _uuid_list in one clause. This is essentially converting this:
|
||||||
|
//
|
||||||
|
// 1,2-3 uuid,uuid uuid 4
|
||||||
|
//
|
||||||
|
// into:
|
||||||
|
//
|
||||||
|
// (
|
||||||
|
// ( id == 1 )
|
||||||
|
// or ( ( id >= 2 ) and ( id <= 3 ) )
|
||||||
|
// or ( id == 4 )
|
||||||
|
// or ( uuid = $UUID )
|
||||||
|
// or ( uuid = $UUID )
|
||||||
|
// )
|
||||||
|
|
||||||
|
A openParen ("argSeq", "("); openParen.tag ("FILTER"); openParen.tag ("OP");
|
||||||
|
A closeParen ("argSeq", ")"); closeParen.tag ("FILTER"); closeParen.tag ("OP");
|
||||||
|
A opOr ("argSeq", "or"); opOr.tag ("FILTER"); opOr.tag ("OP");
|
||||||
|
A opAnd ("argSeq", "and"); opAnd.tag ("FILTER"); opAnd.tag ("OP");
|
||||||
|
A opSimilar ("argSeq", "="); opSimilar.tag ("FILTER"); opSimilar.tag ("OP");
|
||||||
|
A opEqual ("argSeq", "=="); opEqual.tag ("FILTER"); opEqual.tag ("OP");
|
||||||
|
A opGTE ("argSeq", ">="); opGTE.tag ("FILTER"); opGTE.tag ("OP");
|
||||||
|
A opLTE ("argSeq", "<="); opLTE.tag ("FILTER"); opLTE.tag ("OP");
|
||||||
|
|
||||||
|
A argID ("argSeq", "id");
|
||||||
|
argID.tag ("FILTER");
|
||||||
|
argID.tag ("ATTRIBUTE");
|
||||||
|
argID.tag ("OP");
|
||||||
|
|
||||||
|
A argUUID ("argSeq", "uuid");
|
||||||
|
argUUID.tag ("FILTER");
|
||||||
|
argUUID.tag ("ATTRIBUTE");
|
||||||
|
argUUID.tag ("OP");
|
||||||
|
|
||||||
|
reconstructed.push_back (openParen);
|
||||||
|
|
||||||
|
// Add all ID ranges.
|
||||||
|
std::vector <std::pair <int, int> >::iterator r;
|
||||||
|
for (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);
|
||||||
|
|
||||||
|
A value ("argSeq", r->first);
|
||||||
|
value.tag ("FILTER");
|
||||||
|
value.tag ("LITERAL");
|
||||||
|
value.tag ("NUMBER");
|
||||||
|
reconstructed.push_back (value);
|
||||||
|
|
||||||
|
reconstructed.push_back (closeParen);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
reconstructed.push_back (openParen);
|
||||||
|
reconstructed.push_back (argID);
|
||||||
|
reconstructed.push_back (opGTE);
|
||||||
|
|
||||||
|
A startValue ("argSeq", r->first);
|
||||||
|
startValue.tag ("FILTER");
|
||||||
|
startValue.tag ("LITERAL");
|
||||||
|
startValue.tag ("NUMBER");
|
||||||
|
reconstructed.push_back (startValue);
|
||||||
|
|
||||||
|
reconstructed.push_back (opAnd);
|
||||||
|
reconstructed.push_back (argID);
|
||||||
|
reconstructed.push_back (opLTE);
|
||||||
|
|
||||||
|
A endValue ("argSeq", r->second);
|
||||||
|
endValue.tag ("FILTER");
|
||||||
|
endValue.tag ("LITERAL");
|
||||||
|
endValue.tag ("NUMBER");
|
||||||
|
reconstructed.push_back (endValue);
|
||||||
|
|
||||||
|
reconstructed.push_back (closeParen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add all UUID list items.
|
||||||
|
std::vector <std::string>::iterator u;
|
||||||
|
for (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);
|
||||||
|
|
||||||
|
A value ("argSeq", "'" + *u + "'");
|
||||||
|
value.tag ("FILTER");
|
||||||
|
value.tag ("LITERAL");
|
||||||
|
value.tag ("STRING");
|
||||||
|
reconstructed.push_back (value);
|
||||||
|
|
||||||
|
reconstructed.push_back (closeParen);
|
||||||
|
}
|
||||||
|
|
||||||
|
reconstructed.push_back (closeParen);
|
||||||
|
}
|
||||||
|
|
||||||
|
// No 'else' which cause all other ID/UUID args to be eaten.
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
reconstructed.push_back (*a);
|
reconstructed.push_back (*a);
|
||||||
|
|||||||
@@ -85,8 +85,9 @@ private:
|
|||||||
void desugarAttributes ();
|
void desugarAttributes ();
|
||||||
void desugarAttributeModifiers ();
|
void desugarAttributeModifiers ();
|
||||||
void desugarPatterns ();
|
void desugarPatterns ();
|
||||||
void desugarIDs ();
|
void findIDs ();
|
||||||
void desugarUUIDs ();
|
void findUUIDs ();
|
||||||
|
void insertIDExpr ();
|
||||||
void desugarPlainArgs ();
|
void desugarPlainArgs ();
|
||||||
void findOperators ();
|
void findOperators ();
|
||||||
void insertJunctions ();
|
void insertJunctions ();
|
||||||
@@ -100,6 +101,9 @@ public:
|
|||||||
std::map <std::string, std::string> _aliases;
|
std::map <std::string, std::string> _aliases;
|
||||||
std::vector <std::string> _original_args;
|
std::vector <std::string> _original_args;
|
||||||
std::vector <A> _args;
|
std::vector <A> _args;
|
||||||
|
|
||||||
|
std::vector <std::pair <int, int> > _id_ranges;
|
||||||
|
std::vector <std::string> _uuid_list;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user