Enhancements - Config

- Added processing for context.config overrides, and associated
  argc,argv handling.
- Bug fix in filt.t.cpp, but three tests still fail.  Too big a
  distraction to fix right now.
- Warning: build is not broken, but task is broken.
This commit is contained in:
Paul Beckingham 2009-06-07 14:58:32 -04:00
parent 24f31eeb00
commit 190c6b53fc
7 changed files with 211 additions and 210 deletions

View file

@ -103,7 +103,8 @@ bool Att::valid (const std::string& input) const
if (n.skip (':') && if (n.skip (':') &&
(n.getQuoted ('"', ignored) || (n.getQuoted ('"', ignored) ||
n.getUntil (' ', ignored) || n.getUntil (' ', ignored) ||
n.getUntilEOS (ignored))) n.getUntilEOS (ignored) ||
n.depleted ()))
return true; return true;
return false; return false;

View file

@ -85,6 +85,8 @@ Config::Config (const std::string& file)
// not tolerated, but blank lines and comments starting with # are allowed. // not tolerated, but blank lines and comments starting with # are allowed.
bool Config::load (const std::string& file) bool Config::load (const std::string& file)
{ {
this->clear ();
std::ifstream in; std::ifstream in;
in.open (file.c_str (), std::ifstream::in); in.open (file.c_str (), std::ifstream::in);
if (in.good ()) if (in.good ())

View file

@ -145,7 +145,7 @@ void Context::initialize (int argc, char** argv)
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
int Context::run () int Context::run ()
{ {
std::cout << "--- start 1.8.0 ---" << std::endl; std::cout << "--- start 1.8.0 ---" << std::endl;
try try
{ {
parse (); parse ();
@ -177,7 +177,7 @@ int Context::run ()
std::cout << *f << std::endl; std::cout << *f << std::endl;
} }
std::cout << "--- end 1.8.0 ---" << std::endl; std::cout << "--- end 1.8.0 ---" << std::endl;
return 0; return 0;
} }
@ -194,6 +194,9 @@ void Context::loadCorrectConfigFile ()
messages.push_back (std::string ("Using alternate .taskrc file ") + file); // TODO i18n messages.push_back (std::string ("Using alternate .taskrc file ") + file); // TODO i18n
config.load (file); config.load (file);
// No need to handle it again.
args.erase (arg);
} }
} }
@ -224,6 +227,9 @@ void Context::loadCorrectConfigFile ()
messages.push_back (std::string ("Configuration override ") + // TODO i18n messages.push_back (std::string ("Configuration override ") + // TODO i18n
arg->substr (3, std::string::npos)); arg->substr (3, std::string::npos));
} }
// No need to handle it again.
args.erase (arg);
} }
} }
} }
@ -231,119 +237,100 @@ void Context::loadCorrectConfigFile ()
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void Context::parse () void Context::parse ()
{ {
command = ""; command = "";
std::string descCandidate = "";
bool terminated = false; bool terminated = false;
bool foundSequence = false; bool foundSequence = false;
bool foundSomethingAfterSequence = false; bool foundSomethingAfterSequence = false;
std::string descCandidate = "";
foreach (arg, args) foreach (arg, args)
{ {
// Skip any argument that starts with "rc:" or "rc." because it has already if (!terminated)
// been processed.
if (arg->substr (0, 3) != "rc:" ||
arg->substr (0, 3) != "rc.")
{ {
if (!terminated) // The '--' argument shuts off all parsing - everything is an argument.
if (*arg == "--")
terminated = true;
// Sequence
// Note: "add" doesn't require an ID
else if (command != "add" &&
sequence.valid (*arg) &&
! foundSomethingAfterSequence)
{ {
// The '--' argument shuts off all parsing - everything is an argument. std::cout << "# found sequence" << std::endl;
if (*arg == "--") sequence.parse (*arg);
terminated = true; foundSequence = true;
// Sequence
// Note: "add" doesn't require an ID
else if (command != "add" &&
sequence.valid (*arg) &&
! foundSomethingAfterSequence)
{
std::cout << "# found sequence" << std::endl;
sequence.parse (*arg);
foundSequence = true;
}
/*
// Tags begin with + or - and contain arbitrary text.
else if (validTag (arg))
{
if (foundSequence)
foundSomethingAfterSequence = true;
if (arg[0] == '+')
task.addTag (arg->substr (1, std::string::npos));
else if (arg[0] == '-')
task.addRemoveTag (arg->substr (1, std::string::npos));
}
*/
/*
// Attributes contain a constant string followed by a colon, followed by a
// value.
else if ((colon = arg->find (":")) != std::string::npos)
{
if (foundSequence)
foundSomethingAfterSequence = true;
std::string name = lowerCase (arg->substr (0, colon));
std::string value = arg->substr (colon + 1, std::string::npos);
if (validAttribute (name, value))
{
if (name != "recur" || validDuration (value))
task.setAttribute (name, value);
}
// If it is not a valid attribute, then allow the argument as part of
// the description.
else
{
if (descCandidate.length ())
descCandidate += " ";
descCandidate += arg;
}
}
*/
// Substitution of description and/or annotation text.
else if (subst.valid (*arg))
{
if (foundSequence)
foundSomethingAfterSequence = true;
std::cout << "# found subst" << std::endl;
subst.parse (*arg);
}
/*
// Command.
else if (command == "")
{
if (foundSequence)
foundSomethingAfterSequence = true;
std::string l = lowerCase (arg);
if (isCommand (l) && validCommand (l))
command = l;
else
{
if (descCandidate.length ())
descCandidate += " ";
descCandidate += arg;
}
}
*/
// Anything else is just considered description.
else
{
if (foundSequence)
foundSomethingAfterSequence = true;
if (descCandidate.length ())
descCandidate += " ";
descCandidate += *arg;
}
} }
// terminated, therefore everything subsequently is a description. /*
// Tags begin with + or - and contain arbitrary text.
else if (validTag (arg))
{
if (foundSequence)
foundSomethingAfterSequence = true;
if (arg[0] == '+')
task.addTag (arg->substr (1, std::string::npos));
else if (arg[0] == '-')
task.addRemoveTag (arg->substr (1, std::string::npos));
}
*/
/*
// Attributes contain a constant string followed by a colon, followed by a
// value.
else if ((colon = arg->find (":")) != std::string::npos)
{
if (foundSequence)
foundSomethingAfterSequence = true;
std::string name = lowerCase (arg->substr (0, colon));
std::string value = arg->substr (colon + 1, std::string::npos);
if (validAttribute (name, value))
{
if (name != "recur" || validDuration (value))
task.setAttribute (name, value);
}
// If it is not a valid attribute, then allow the argument as part of
// the description.
else
{
if (descCandidate.length ())
descCandidate += " ";
descCandidate += arg;
}
}
*/
// Substitution of description and/or annotation text.
else if (subst.valid (*arg))
{
if (foundSequence)
foundSomethingAfterSequence = true;
std::cout << "# found subst" << std::endl;
subst.parse (*arg);
}
/*
// Command.
else if (command == "")
{
if (foundSequence)
foundSomethingAfterSequence = true;
std::string l = lowerCase (arg);
if (isCommand (l) && validCommand (l))
command = l;
else
{
if (descCandidate.length ())
descCandidate += " ";
descCandidate += arg;
}
}
*/
// Anything else is just considered description.
else else
{ {
if (foundSequence) if (foundSequence)
@ -354,6 +341,17 @@ void Context::parse ()
descCandidate += *arg; descCandidate += *arg;
} }
} }
// terminated, therefore everything subsequently is a description.
else
{
if (foundSequence)
foundSomethingAfterSequence = true;
if (descCandidate.length ())
descCandidate += " ";
descCandidate += *arg;
}
} }
if (validDescription (descCandidate)) if (validDescription (descCandidate))

View file

@ -440,108 +440,93 @@ void parse (
{ {
std::string arg (args[i]); std::string arg (args[i]);
// Ignore any argument that is "rc:...", because that is the command line if (!terminated)
// specified rc file.
if (arg.substr (0, 3) != "rc:")
{ {
if (!terminated) size_t colon; // Pointer to colon in argument.
std::string from;
std::string to;
bool global;
std::vector <int> sequence;
// The '--' argument shuts off all parsing - everything is an argument.
if (arg == "--")
terminated = true;
// An id is the first argument found that contains all digits.
else if (lowerCase (command) != "add" && // "add" doesn't require an ID
validSequence (arg, sequence) &&
! foundSomethingAfterSequence)
{ {
size_t colon; // Pointer to colon in argument. foundSequence = true;
std::string from; foreach (id, sequence)
std::string to; task.addId (*id);
bool global; }
std::vector <int> sequence;
// The '--' argument shuts off all parsing - everything is an argument. // Tags begin with + or - and contain arbitrary text.
if (arg == "--") else if (validTag (arg))
terminated = true; {
if (foundSequence)
foundSomethingAfterSequence = true;
// An id is the first argument found that contains all digits. if (arg[0] == '+')
else if (lowerCase (command) != "add" && // "add" doesn't require an ID task.addTag (arg.substr (1, std::string::npos));
validSequence (arg, sequence) && else if (arg[0] == '-')
! foundSomethingAfterSequence) task.addRemoveTag (arg.substr (1, std::string::npos));
}
// Attributes contain a constant string followed by a colon, followed by a
// value.
else if ((colon = arg.find (":")) != std::string::npos)
{
if (foundSequence)
foundSomethingAfterSequence = true;
std::string name = lowerCase (arg.substr (0, colon));
std::string value = arg.substr (colon + 1, std::string::npos);
if (validAttribute (name, value))
{ {
foundSequence = true; if (name != "recur" || validDuration (value))
foreach (id, sequence) task.setAttribute (name, value);
task.addId (*id);
} }
// Tags begin with + or - and contain arbitrary text. // If it is not a valid attribute, then allow the argument as part of
else if (validTag (arg)) // the description.
{
if (foundSequence)
foundSomethingAfterSequence = true;
if (arg[0] == '+')
task.addTag (arg.substr (1, std::string::npos));
else if (arg[0] == '-')
task.addRemoveTag (arg.substr (1, std::string::npos));
}
// Attributes contain a constant string followed by a colon, followed by a
// value.
else if ((colon = arg.find (":")) != std::string::npos)
{
if (foundSequence)
foundSomethingAfterSequence = true;
std::string name = lowerCase (arg.substr (0, colon));
std::string value = arg.substr (colon + 1, std::string::npos);
if (validAttribute (name, value))
{
if (name != "recur" || validDuration (value))
task.setAttribute (name, value);
}
// If it is not a valid attribute, then allow the argument as part of
// the description.
else
{
if (descCandidate.length ())
descCandidate += " ";
descCandidate += arg;
}
}
// Substitution of description text.
else if (validSubstitution (arg, from, to, global))
{
if (foundSequence)
foundSomethingAfterSequence = true;
task.setSubstitution (from, to, global);
}
// Command.
else if (command == "")
{
if (foundSequence)
foundSomethingAfterSequence = true;
std::string l = lowerCase (arg);
if (isCommand (l) && validCommand (l))
command = l;
else
{
if (descCandidate.length ())
descCandidate += " ";
descCandidate += arg;
}
}
// Anything else is just considered description.
else else
{ {
if (foundSequence)
foundSomethingAfterSequence = true;
if (descCandidate.length ()) if (descCandidate.length ())
descCandidate += " "; descCandidate += " ";
descCandidate += arg; descCandidate += arg;
} }
} }
// terminated, therefore everything subsequently is a description.
// Substitution of description text.
else if (validSubstitution (arg, from, to, global))
{
if (foundSequence)
foundSomethingAfterSequence = true;
task.setSubstitution (from, to, global);
}
// Command.
else if (command == "")
{
if (foundSequence)
foundSomethingAfterSequence = true;
std::string l = lowerCase (arg);
if (isCommand (l) && validCommand (l))
command = l;
else
{
if (descCandidate.length ())
descCandidate += " ";
descCandidate += arg;
}
}
// Anything else is just considered description.
else else
{ {
if (foundSequence) if (foundSequence)
@ -552,6 +537,16 @@ void parse (
descCandidate += arg; descCandidate += arg;
} }
} }
// terminated, therefore everything subsequently is a description.
else
{
if (foundSequence)
foundSomethingAfterSequence = true;
if (descCandidate.length ())
descCandidate += " ";
descCandidate += arg;
}
} }
if (validDescription (descCandidate)) if (validDescription (descCandidate))

View file

@ -35,7 +35,7 @@
#include <pwd.h> #include <pwd.h>
#include <time.h> #include <time.h>
#include "Config.h" #include "Context.h"
#include "Date.h" #include "Date.h"
#include "Table.h" #include "Table.h"
#include "TDB.h" #include "TDB.h"

View file

@ -36,7 +36,7 @@
#include <pwd.h> #include <pwd.h>
#include <time.h> #include <time.h>
#include "Config.h" #include "Context.h"
#include "Date.h" #include "Date.h"
#include "Duration.h" #include "Duration.h"
#include "Table.h" #include "Table.h"
@ -299,13 +299,15 @@ int main (int argc, char** argv)
srand (time (NULL)); srand (time (NULL));
#endif #endif
int status = 0;
try try
{ {
context.initialize (argc, argv); context.initialize (argc, argv);
if (context.args[0].find ("itask") != std::string::npos) if (context.args[0].find ("itask") != std::string::npos)
/* return */ context.interactive (); status = context.interactive ();
else else
/* return */ context.run (); status = context.run ();
// start OBSOLETE // start OBSOLETE
TDB tdb; TDB tdb;
@ -329,7 +331,7 @@ int main (int argc, char** argv)
"overwrite your completed tasks. Please change it."); "overwrite your completed tasks. Please change it.");
} }
std::cout << runTaskCommand (argc, argv, tdb); std::cout << runTaskCommand (context.args, tdb);
} }
catch (std::string& error) catch (std::string& error)
@ -345,7 +347,7 @@ int main (int argc, char** argv)
} }
// end OBSOLETE // end OBSOLETE
return 0; return status;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -812,7 +814,12 @@ std::string runTaskCommand (
{ {
std::vector <std::string> args; std::vector <std::string> args;
for (int i = 1; i < argc; ++i) for (int i = 1; i < argc; ++i)
args.push_back (argv[i]); if (strncmp (argv[i], "rc:", 3) &&
strncmp (argv[i], "rc.", 3))
{
std::cout << "arg=" << argv[i] << std::endl;
args.push_back (argv[i]);
}
return runTaskCommand (args, tdb, gc, shadow); return runTaskCommand (args, tdb, gc, shadow);
} }
@ -824,12 +831,10 @@ std::string runTaskCommand (
bool gc /* = false */, bool gc /* = false */,
bool shadow /* = false */) bool shadow /* = false */)
{ {
// If argc == 1 and the default.command configuration variable is set, // If argc == 1 and there is a default.command, use it. Otherwise use
// then use that, otherwise stick with argc/argv. // argc/argv.
std::string defaultCommand = context.config.get ("default.command"); std::string defaultCommand = context.config.get ("default.command");
if ((args.size () == 0 || if (args.size () == 0 || defaultCommand != "")
(args.size () == 1 && args[0].substr (0, 3) == "rc:")) &&
defaultCommand != "")
{ {
// Stuff the command line. // Stuff the command line.
args.clear (); args.clear ();

View file

@ -57,11 +57,11 @@ int main (int argc, char** argv)
T2 no1; T2 no1;
no1.set ("name3", "value3"); no1.set ("name3", "value3");
test.notok (f.pass (no0), "no match against mismatch T2"); test.notok (f.pass (no1), "no match against mismatch T2");
T2 partial; T2 partial;
partial.set ("name1", "value1"); partial.set ("name1", "value1");
test.notok (f.pass (no0), "no match against partial T2"); test.notok (f.pass (partial), "no match against partial T2");
// Modifiers. // Modifiers.
T2 mods; T2 mods;