mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-09-09 00:30:36 +02:00
A3t::findAttribute
- FindAttribute implemented, supporting pseudo- and uda- attribute recognition, which is an improvement. - Fully parsed arguments are now locked against further parsing. - Validation consists of looking for unlocked args. - Added more entities for testing. - Updated test script.
This commit is contained in:
parent
5a29042d3b
commit
04fb751678
4 changed files with 126 additions and 6 deletions
|
@ -65,6 +65,7 @@ Tree* A3t::parse ()
|
||||||
findSubstitution ();
|
findSubstitution ();
|
||||||
findPattern ();
|
findPattern ();
|
||||||
findTag ();
|
findTag ();
|
||||||
|
findAttribute ();
|
||||||
|
|
||||||
validate ();
|
validate ();
|
||||||
|
|
||||||
|
@ -116,6 +117,7 @@ void A3t::findBinary ()
|
||||||
if (_tree->_branches.size () >= 1)
|
if (_tree->_branches.size () >= 1)
|
||||||
{
|
{
|
||||||
_tree->_branches[0]->tag ("BINARY");
|
_tree->_branches[0]->tag ("BINARY");
|
||||||
|
_tree->_branches[0]->tag ("LOCK");
|
||||||
std::string binary = _tree->_branches[0]->attribute ("raw");
|
std::string binary = _tree->_branches[0]->attribute ("raw");
|
||||||
std::string::size_type slash = binary.rfind ('/');
|
std::string::size_type slash = binary.rfind ('/');
|
||||||
if (slash != std::string::npos)
|
if (slash != std::string::npos)
|
||||||
|
@ -125,7 +127,7 @@ void A3t::findBinary ()
|
||||||
|
|
||||||
if (binary == "cal" || binary == "calendar")
|
if (binary == "cal" || binary == "calendar")
|
||||||
_tree->_branches[0]->tag ("CALENDAR");
|
_tree->_branches[0]->tag ("CALENDAR");
|
||||||
else
|
else if (binary == "task" || binary == "tw" || binary == "t")
|
||||||
_tree->_branches[0]->tag ("TW");
|
_tree->_branches[0]->tag ("TW");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -135,13 +137,20 @@ void A3t::findBinary ()
|
||||||
// all args in the raw state.
|
// all args in the raw state.
|
||||||
void A3t::findTerminator ()
|
void A3t::findTerminator ()
|
||||||
{
|
{
|
||||||
|
bool found = false;
|
||||||
std::vector <Tree*>::iterator i;
|
std::vector <Tree*>::iterator i;
|
||||||
for (i = _tree->_branches.begin (); i != _tree->_branches.end (); ++i)
|
for (i = _tree->_branches.begin (); i != _tree->_branches.end (); ++i)
|
||||||
{
|
{
|
||||||
if ((*i)->attribute ("raw") == "--")
|
if ((*i)->attribute ("raw") == "--")
|
||||||
{
|
{
|
||||||
(*i)->tag ("TERMINATOR");
|
(*i)->tag ("TERMINATOR");
|
||||||
break;
|
(*i)->tag ("LOCK");
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
else if (found)
|
||||||
|
{
|
||||||
|
(*i)->tag ("WORD");
|
||||||
|
(*i)->tag ("LOCK");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -159,11 +168,16 @@ void A3t::findCommand ()
|
||||||
if ((*i)->attribute ("raw") == "--")
|
if ((*i)->attribute ("raw") == "--")
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// Skip locked args.
|
||||||
|
if ((*i)->hasTag ("LOCK"))
|
||||||
|
continue;
|
||||||
|
|
||||||
if (canonicalize (command, "report", (*i)->attribute ("raw")))
|
if (canonicalize (command, "report", (*i)->attribute ("raw")))
|
||||||
{
|
{
|
||||||
(*i)->attribute ("canonical", command);
|
(*i)->attribute ("canonical", command);
|
||||||
(*i)->tag ("REPORT");
|
(*i)->tag ("REPORT");
|
||||||
(*i)->tag ("CMD");
|
(*i)->tag ("CMD");
|
||||||
|
(*i)->tag ("LOCK");
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (canonicalize (command, "readcmd", (*i)->attribute ("raw")))
|
else if (canonicalize (command, "readcmd", (*i)->attribute ("raw")))
|
||||||
|
@ -171,6 +185,7 @@ void A3t::findCommand ()
|
||||||
(*i)->attribute ("canonical", command);
|
(*i)->attribute ("canonical", command);
|
||||||
(*i)->tag ("READCMD");
|
(*i)->tag ("READCMD");
|
||||||
(*i)->tag ("CMD");
|
(*i)->tag ("CMD");
|
||||||
|
(*i)->tag ("LOCK");
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (canonicalize (command, "writecmd", (*i)->attribute ("raw")))
|
else if (canonicalize (command, "writecmd", (*i)->attribute ("raw")))
|
||||||
|
@ -178,6 +193,7 @@ void A3t::findCommand ()
|
||||||
(*i)->attribute ("canonical", command);
|
(*i)->attribute ("canonical", command);
|
||||||
(*i)->tag ("WRITECMD");
|
(*i)->tag ("WRITECMD");
|
||||||
(*i)->tag ("CMD");
|
(*i)->tag ("CMD");
|
||||||
|
(*i)->tag ("LOCK");
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (canonicalize (command, "specialcmd", (*i)->attribute ("raw")))
|
else if (canonicalize (command, "specialcmd", (*i)->attribute ("raw")))
|
||||||
|
@ -185,6 +201,7 @@ void A3t::findCommand ()
|
||||||
(*i)->attribute ("canonical", command);
|
(*i)->attribute ("canonical", command);
|
||||||
(*i)->tag ("SPECIALCMD");
|
(*i)->tag ("SPECIALCMD");
|
||||||
(*i)->tag ("CMD");
|
(*i)->tag ("CMD");
|
||||||
|
(*i)->tag ("LOCK");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -199,10 +216,15 @@ void A3t::findFileOverride ()
|
||||||
if ((*i)->attribute ("raw") == "--")
|
if ((*i)->attribute ("raw") == "--")
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// Skip locked args.
|
||||||
|
if ((*i)->hasTag ("LOCK"))
|
||||||
|
continue;
|
||||||
|
|
||||||
std::string arg = (*i)->attribute ("raw");
|
std::string arg = (*i)->attribute ("raw");
|
||||||
if (arg.find ("rc:") == 0)
|
if (arg.find ("rc:") == 0)
|
||||||
{
|
{
|
||||||
(*i)->tag ("RC");
|
(*i)->tag ("RC");
|
||||||
|
(*i)->tag ("LOCK");
|
||||||
Tree* b = (*i)->addBranch (new Tree ("metadata"));
|
Tree* b = (*i)->addBranch (new Tree ("metadata"));
|
||||||
b->attribute ("file", arg.substr (3));
|
b->attribute ("file", arg.substr (3));
|
||||||
}
|
}
|
||||||
|
@ -220,6 +242,10 @@ void A3t::findConfigOverride ()
|
||||||
if ((*i)->attribute ("raw") == "--")
|
if ((*i)->attribute ("raw") == "--")
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// Skip locked args.
|
||||||
|
if ((*i)->hasTag ("LOCK"))
|
||||||
|
continue;
|
||||||
|
|
||||||
std::string arg = (*i)->attribute ("raw");
|
std::string arg = (*i)->attribute ("raw");
|
||||||
if (arg.find ("rc.") == 0)
|
if (arg.find ("rc.") == 0)
|
||||||
{
|
{
|
||||||
|
@ -230,6 +256,7 @@ void A3t::findConfigOverride ()
|
||||||
if (sep != std::string::npos)
|
if (sep != std::string::npos)
|
||||||
{
|
{
|
||||||
(*i)->tag ("CONFIG");
|
(*i)->tag ("CONFIG");
|
||||||
|
(*i)->tag ("LOCK");
|
||||||
Tree* b = (*i)->addBranch (new Tree ("metadata"));
|
Tree* b = (*i)->addBranch (new Tree ("metadata"));
|
||||||
b->attribute ("name", arg.substr (3, sep - 3));
|
b->attribute ("name", arg.substr (3, sep - 3));
|
||||||
b->attribute ("value", arg.substr (sep + 1));
|
b->attribute ("value", arg.substr (sep + 1));
|
||||||
|
@ -249,6 +276,10 @@ void A3t::findPattern ()
|
||||||
if ((*i)->attribute ("raw") == "--")
|
if ((*i)->attribute ("raw") == "--")
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// Skip locked args.
|
||||||
|
if ((*i)->hasTag ("LOCK"))
|
||||||
|
continue;
|
||||||
|
|
||||||
Nibbler n ((*i)->attribute ("raw"));
|
Nibbler n ((*i)->attribute ("raw"));
|
||||||
std::string pattern;
|
std::string pattern;
|
||||||
if (n.getQuoted ('/', pattern) &&
|
if (n.getQuoted ('/', pattern) &&
|
||||||
|
@ -256,6 +287,7 @@ void A3t::findPattern ()
|
||||||
pattern.length () > 0)
|
pattern.length () > 0)
|
||||||
{
|
{
|
||||||
(*i)->tag ("PATTERN");
|
(*i)->tag ("PATTERN");
|
||||||
|
(*i)->tag ("LOCK");
|
||||||
Tree* b = (*i)->addBranch (new Tree ("metadata"));
|
Tree* b = (*i)->addBranch (new Tree ("metadata"));
|
||||||
b->attribute ("pattern", pattern);
|
b->attribute ("pattern", pattern);
|
||||||
}
|
}
|
||||||
|
@ -273,6 +305,10 @@ void A3t::findSubstitution ()
|
||||||
if ((*i)->attribute ("raw") == "--")
|
if ((*i)->attribute ("raw") == "--")
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// Skip locked args.
|
||||||
|
if ((*i)->hasTag ("LOCK"))
|
||||||
|
continue;
|
||||||
|
|
||||||
std::string raw = (*i)->attribute ("raw");
|
std::string raw = (*i)->attribute ("raw");
|
||||||
Nibbler n (raw);
|
Nibbler n (raw);
|
||||||
|
|
||||||
|
@ -290,6 +326,7 @@ void A3t::findSubstitution ()
|
||||||
!Directory (raw).exists ())
|
!Directory (raw).exists ())
|
||||||
{
|
{
|
||||||
(*i)->tag ("SUBSTITUTION");
|
(*i)->tag ("SUBSTITUTION");
|
||||||
|
(*i)->tag ("LOCK");
|
||||||
Tree* b = (*i)->addBranch (new Tree ("metadata"));
|
Tree* b = (*i)->addBranch (new Tree ("metadata"));
|
||||||
b->attribute ("from", from);
|
b->attribute ("from", from);
|
||||||
b->attribute ("to", to);
|
b->attribute ("to", to);
|
||||||
|
@ -310,6 +347,10 @@ void A3t::findTag ()
|
||||||
if ((*i)->attribute ("raw") == "--")
|
if ((*i)->attribute ("raw") == "--")
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// Skip locked args.
|
||||||
|
if ((*i)->hasTag ("LOCK"))
|
||||||
|
continue;
|
||||||
|
|
||||||
std::string raw = (*i)->attribute ("raw");
|
std::string raw = (*i)->attribute ("raw");
|
||||||
Nibbler n (raw);
|
Nibbler n (raw);
|
||||||
|
|
||||||
|
@ -321,6 +362,7 @@ void A3t::findTag ()
|
||||||
tag.find (' ') == std::string::npos)
|
tag.find (' ') == std::string::npos)
|
||||||
{
|
{
|
||||||
(*i)->tag ("TAG");
|
(*i)->tag ("TAG");
|
||||||
|
(*i)->tag ("LOCK");
|
||||||
Tree* b = (*i)->addBranch (new Tree ("metadata"));
|
Tree* b = (*i)->addBranch (new Tree ("metadata"));
|
||||||
b->attribute ("sign", sign);
|
b->attribute ("sign", sign);
|
||||||
b->attribute ("tag", tag);
|
b->attribute ("tag", tag);
|
||||||
|
@ -328,10 +370,72 @@ void A3t::findTag ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// <name>:['"][<value>]['"]
|
||||||
|
void A3t::findAttribute ()
|
||||||
|
{
|
||||||
|
std::vector <Tree*>::iterator i;
|
||||||
|
for (i = _tree->_branches.begin (); i != _tree->_branches.end (); ++i)
|
||||||
|
{
|
||||||
|
// Parser override operator.
|
||||||
|
if ((*i)->attribute ("raw") == "--")
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Skip locked args.
|
||||||
|
if ((*i)->hasTag ("LOCK"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
std::string raw = (*i)->attribute ("raw");
|
||||||
|
Nibbler n (raw);
|
||||||
|
|
||||||
|
// Look for a valid attribute name.
|
||||||
|
std::string name;
|
||||||
|
if (n.getName (name) &&
|
||||||
|
name.length ())
|
||||||
|
{
|
||||||
|
if (n.skip (':'))
|
||||||
|
{
|
||||||
|
std::string value;
|
||||||
|
if (n.getUntilEOS (value))
|
||||||
|
{
|
||||||
|
Tree* b = (*i)->addBranch (new Tree ("metadata"));
|
||||||
|
b->attribute ("value", value);
|
||||||
|
|
||||||
|
std::string canonical;
|
||||||
|
if (canonicalize (canonical, "attribute", name))
|
||||||
|
{
|
||||||
|
(*i)->tag ("ATTRIBUTE");
|
||||||
|
(*i)->tag ("LOCK");
|
||||||
|
b->attribute ("name", canonical);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (canonicalize (canonical, "uda", name))
|
||||||
|
(*i)->tag ("UDA");
|
||||||
|
|
||||||
|
if (canonicalize (canonical, "pseudo", name))
|
||||||
|
{
|
||||||
|
(*i)->tag ("PSEUDO");
|
||||||
|
(*i)->tag ("LOCK");
|
||||||
|
b->attribute ("name", canonical);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Validate the parse tree.
|
// Validate the parse tree.
|
||||||
void A3t::validate ()
|
void A3t::validate ()
|
||||||
{
|
{
|
||||||
|
// Look for any unrecognized original args.
|
||||||
|
std::vector <Tree*>::iterator i;
|
||||||
|
for (i = _tree->_branches.begin (); i != _tree->_branches.end (); ++i)
|
||||||
|
if ((*i)->hasTag ("ORIGINAL") &&
|
||||||
|
! (*i)->hasTag ("LOCK"))
|
||||||
|
//throw std::string ("Unrecognized argument '") + (*i)->attribute ("raw") + "'";
|
||||||
|
std::cout << "Unrecognized argument '" << (*i)->attribute ("raw") << "'\n";
|
||||||
|
|
||||||
// TODO Any RC node must have a root/*[+RC]/data[@file] that exists.
|
// TODO Any RC node must have a root/*[+RC]/data[@file] that exists.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,7 @@ private:
|
||||||
void findPattern ();
|
void findPattern ();
|
||||||
void findSubstitution ();
|
void findSubstitution ();
|
||||||
void findTag ();
|
void findTag ();
|
||||||
|
void findAttribute ();
|
||||||
void validate ();
|
void validate ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -28,8 +28,6 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <Context.h>
|
#include <Context.h>
|
||||||
#include <A3t.h>
|
#include <A3t.h>
|
||||||
//#include <Tree.h>
|
|
||||||
//#include <text.h>
|
|
||||||
|
|
||||||
Context context;
|
Context context;
|
||||||
|
|
||||||
|
@ -40,19 +38,36 @@ int main (int argc, char** argv)
|
||||||
{
|
{
|
||||||
A3t a3t (argc, argv);
|
A3t a3t (argc, argv);
|
||||||
|
|
||||||
// Populate identity lists.
|
// Reports.
|
||||||
a3t.identity ("report", "list");
|
a3t.identity ("report", "list");
|
||||||
a3t.identity ("report", "next");
|
a3t.identity ("report", "next");
|
||||||
|
|
||||||
|
// Read-only commands.
|
||||||
a3t.identity ("readcmd", "info");
|
a3t.identity ("readcmd", "info");
|
||||||
a3t.identity ("readcmd", "projects");
|
a3t.identity ("readcmd", "projects");
|
||||||
|
|
||||||
|
// Write commands.
|
||||||
a3t.identity ("writecmd", "add");
|
a3t.identity ("writecmd", "add");
|
||||||
a3t.identity ("writecmd", "modify");
|
a3t.identity ("writecmd", "modify");
|
||||||
|
|
||||||
|
// Special commands.
|
||||||
a3t.identity ("specialcmd", "calendar");
|
a3t.identity ("specialcmd", "calendar");
|
||||||
a3t.identity ("specialcmd", "edit");
|
a3t.identity ("specialcmd", "edit");
|
||||||
|
|
||||||
|
// Attributes (columns).
|
||||||
|
a3t.identity ("attribute", "description");
|
||||||
|
a3t.identity ("attribute", "due");
|
||||||
|
a3t.identity ("attribute", "priority");
|
||||||
|
a3t.identity ("attribute", "project");
|
||||||
|
a3t.identity ("attribute", "uuid");
|
||||||
|
a3t.identity ("attribute", "duration"); // UDAs are included.
|
||||||
|
|
||||||
|
// Pseudo-attributes.
|
||||||
|
a3t.identity ("pseudo", "limit");
|
||||||
|
|
||||||
|
// UDAs.
|
||||||
|
a3t.identity ("uda", "duration");
|
||||||
|
|
||||||
Tree* tree = a3t.parse ();
|
Tree* tree = a3t.parse ();
|
||||||
if (tree)
|
if (tree)
|
||||||
tree->dump ();
|
tree->dump ();
|
||||||
|
|
|
@ -10,5 +10,5 @@
|
||||||
|
|
||||||
echo; ./args rc:~/.taskrc 123 mod pro:'P 1' +home /from/to/g /from/to/ rc.name=value
|
echo; ./args rc:~/.taskrc 123 mod pro:'P 1' +home /from/to/g /from/to/ rc.name=value
|
||||||
echo; ./args rc:~/..taskrc rc.name=value add -- modify +tag /from/to/g name:value /long/path/to/file.txt
|
echo; ./args rc:~/..taskrc rc.name=value add -- modify +tag /from/to/g name:value /long/path/to/file.txt
|
||||||
echo; ./args /pattern/ nex
|
echo; ./args /pattern/ limit:10 nex
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue