Expressions reboot

- Now handles argument captures from argv, stdin.
- Now handles rc overrides, aliases, default command.
This commit is contained in:
Paul Beckingham 2011-07-23 15:24:39 -04:00
parent 5b5978952a
commit 4fc4e0f637
3 changed files with 105 additions and 95 deletions

View file

@ -241,20 +241,10 @@ bool A3::is_command (
return false;
}
#ifdef NOPE
////////////////////////////////////////////////////////////////////////////////
// Add a pair for every word from std::cin, with a category of "".
void A3::append_stdin ()
{
bool something_happened = false;
// Use 'select' to determine whether there is any std::cin content buffered
// before trying to read it, to prevent blocking.
struct timeval tv;
@ -273,13 +263,9 @@ void A3::append_stdin ()
if (arg == "--")
break;
this->push_back (Arg (arg, "", ""));
something_happened = true;
this->push_back (Arg (arg, ""));
}
}
if (something_happened)
categorize ();
}
////////////////////////////////////////////////////////////////////////////////
@ -291,9 +277,9 @@ void A3::rc_override (
std::vector <Arg>::iterator arg;
for (arg = this->begin (); arg != this->end (); ++arg)
{
if (arg->_third == "rc")
if (arg->_category == "rc")
{
rc = File (arg->_first.substr (3));
rc = File (arg->_raw.substr (3));
home = rc;
std::string::size_type last_slash = rc.data.rfind ("/");
@ -304,7 +290,7 @@ void A3::rc_override (
context.header ("Using alternate .taskrc file " + rc.data);
// Keep scanning, because if there are multiple rc:file arguments, we
// Keep looping, because if there are multiple rc:file arguments, we
// want the last one to dominate.
}
}
@ -321,46 +307,18 @@ void A3::get_data_location (std::string& data)
std::vector <Arg>::iterator arg;
for (arg = this->begin (); arg != this->end (); ++arg)
{
if (arg->_third == "override")
if (arg->_category == "override")
{
if (arg->_first.substr (0, 16) == "rc.data.location" &&
arg->_first[16] == ':')
if (arg->_raw.substr (0, 16) == "rc.data.location" &&
(arg->_raw[16] == ':' || arg->_raw[16] == '='))
{
data = arg->_first.substr (17);
data = arg->_raw.substr (17);
context.header ("Using alternate data.location " + data);
}
}
// Keep scanning, because if there are multiple rc:file arguments, we
// want the last one to dominate.
}
}
////////////////////////////////////////////////////////////////////////////////
// Extracts any rc.name:value args and sets the name/value in context.config,
// leaving only the plain args.
void A3::apply_overrides ()
{
std::vector <Arg>::iterator arg;
for (arg = this->begin (); arg != this->end (); ++arg)
{
if (arg->_third == "override")
{
std::string name;
std::string value;
Nibbler n (arg->_first);
if (n.getLiteral ("rc.") && // rc.
n.getUntil (':', name) && // xxx
n.skip (':')) // :
{
n.getUntilEOS (value); // May be blank.
context.config.set (name, value);
context.footnote ("Configuration override rc." + name + ":" + value);
}
else
context.footnote ("Problem with override: " + arg->_first);
}
// Keep scanning, because if there are multiple overrides, we want the last
// one to dominate.
}
}
@ -380,18 +338,18 @@ void A3::resolve_aliases ()
for (arg = this->begin (); arg != this->end (); ++arg)
{
std::map <std::string, std::string>::iterator match =
context.aliases.find (arg->_first);
context.aliases.find (arg->_raw);
if (match != context.aliases.end ())
{
context.debug (std::string ("A3::resolve_aliases '")
+ arg->_first
+ arg->_raw
+ "' --> '"
+ context.aliases[arg->_first]
+ context.aliases[arg->_raw]
+ "'");
std::vector <std::string> words;
splitq (words, context.aliases[arg->_first], ' ');
splitq (words, context.aliases[arg->_raw], ' ');
std::vector <std::string>::iterator word;
for (word = words.begin (); word != words.end (); ++word)
@ -400,7 +358,7 @@ void A3::resolve_aliases ()
something = true;
}
else
expanded.push_back (arg->_first);
expanded.push_back (arg->_raw);
}
// Only overwrite if something happened.
@ -409,13 +367,43 @@ void A3::resolve_aliases ()
this->clear ();
std::vector <std::string>::iterator e;
for (e = expanded.begin (); e != expanded.end (); ++e)
this->push_back (Arg (*e, "", ""));
this->push_back (Arg (*e, ""));
expanded.clear ();
categorize ();
}
}
while (something && --safety_valve > 0);
if (safety_valve <= 0)
context.debug ("Nested alias limit of 10 reached.");
}
////////////////////////////////////////////////////////////////////////////////
// Extracts any rc.name:value args and sets the name/value in context.config,
// leaving only the plain args.
void A3::apply_overrides ()
{
std::vector <Arg>::iterator arg;
for (arg = this->begin (); arg != this->end (); ++arg)
{
if (arg->_category == "override")
{
std::string name;
std::string value;
Nibbler n (arg->_raw);
if (n.getLiteral ("rc.") && // rc.
n.getUntilOneOf (":=", name) && // xxx
(n.skip (':') || n.skip ('='))) // [:=]
{
n.getUntilEOS (value); // May be blank.
context.config.set (name, value);
context.footnote ("Configuration override rc." + name + ":" + value);
}
else
context.footnote ("Problem with override: " + arg->_raw);
}
}
}
////////////////////////////////////////////////////////////////////////////////
@ -430,16 +418,18 @@ void A3::inject_defaults ()
std::vector <Arg>::iterator arg;
for (arg = this->begin (); arg != this->end (); ++arg)
{
if (arg->_third == "command")
if (arg->_category == "command")
found_command = true;
else if (arg->_third == "id" ||
arg->_third == "uuid")
/* TODO no "id" or "uuid" categories exist at this time. Hmm.
else if (arg->_category == "id" ||
arg->_category == "uuid")
found_sequence = true;
*/
else if (arg->_third != "program" &&
arg->_third != "override" &&
arg->_third != "rc")
else if (arg->_category != "program" &&
arg->_category != "override" &&
arg->_category != "rc")
found_other = true;
}
@ -478,16 +468,47 @@ void A3::inject_defaults ()
}
////////////////////////////////////////////////////////////////////////////////
std::vector <std::string> A3::list ()
const std::string A3::combine () const
{
std::string combined;
std::vector <Arg>::const_iterator arg;
for (arg = this->begin (); arg != this->end (); ++arg)
{
if (arg != this->begin ())
combined += " ";
combined += arg->_raw;
}
return combined;
}
////////////////////////////////////////////////////////////////////////////////
const std::vector <std::string> A3::list () const
{
std::vector <std::string> all;
std::vector <Arg>::iterator arg;
std::vector <Arg>::const_iterator arg;
for (arg = this->begin (); arg != this->end (); ++arg)
all.push_back (arg->_first);
all.push_back (arg->_raw);
return all;
}
#ifdef NOPE
////////////////////////////////////////////////////////////////////////////////
std::vector <std::string> A3::operator_list ()
{
@ -498,23 +519,6 @@ std::vector <std::string> A3::operator_list ()
return all;
}
////////////////////////////////////////////////////////////////////////////////
std::string A3::combine ()
{
std::string combined;
std::vector <Arg>::iterator arg;
for (arg = this->begin (); arg != this->end (); ++arg)
{
if (arg != this->begin ())
combined += " ";
combined += arg->_first;
}
return combined;
}
////////////////////////////////////////////////////////////////////////////////
bool A3::find_command (std::string& command)
{

View file

@ -84,20 +84,20 @@ public:
void capture_first (const std::string&);
void categorize ();
static bool is_command (const std::vector <std::string>&, std::string&);
/*
void append_stdin ();
void rc_override (std::string&, File&);
void get_data_location (std::string&);
void apply_overrides ();
void resolve_aliases ();
void apply_overrides ();
void inject_defaults ();
std::vector <std::string> list ();
const std::string combine () const;
const std::vector <std::string> list () const;
/*
static std::vector <std::string> operator_list ();
std::string combine ();
bool find_command (std::string&);
std::string find_limit ();

View file

@ -79,6 +79,7 @@ int Context::initialize (int argc, const char** argv)
// echo one two -- three | task zero --> task zero one two
// 'three' is left in the input buffer.
args.append_stdin ();
a3.append_stdin ();
// Assume default .taskrc and .task locations.
assumeLocations ();
@ -86,6 +87,8 @@ int Context::initialize (int argc, const char** argv)
// Process 'rc:<file>' command line override, and remove the argument from the
// Context::args.
args.rc_override (home_dir, rc_file);
a3.categorize ();
a3.rc_override (home_dir, rc_file);
// Dump any existing values and load rc file.
config.clear ();
@ -95,7 +98,8 @@ int Context::initialize (int argc, const char** argv)
// location (~/.task), or set by data.location in the config file, or
// overridden by rc.data.location on the command line.
std::string location;
args.get_data_location (location);
// args.get_data_location (location);
a3.get_data_location (location);
data_dir = Directory (location);
extension_dir = data_dir.data + "/extensions";
@ -105,9 +109,11 @@ int Context::initialize (int argc, const char** argv)
// Handle Aliases.
loadAliases ();
args.resolve_aliases ();
a3.resolve_aliases ();
// Apply rc overrides to Context::config, capturing raw args for later use.
args.apply_overrides ();
// args.apply_overrides ();
a3.apply_overrides ();
// Initialize the color rules, if necessary.
if (color ())
@ -121,12 +127,12 @@ int Context::initialize (int argc, const char** argv)
// Categorize all arguments one more time. THIS IS NECESSARY.
args.categorize ();
a3.categorize ();
a3.dump ("Initial"); // TODO Remove.
// Handle default command and assumed 'info' command.
args.inject_defaults ();
a3.inject_defaults ();
a3.dump ("Context::initialize"); // TODO Remove.
// TODO Instantiate extension command objects.
// TODO Instantiate default command object.
@ -532,7 +538,7 @@ void Context::updateXtermTitle ()
args.find_command (command);
std::string title;
join (title, " ", args.list ());
join (title, " ", a3.list ());
std::cout << "]0;task " << command << " " << title << "" << std::endl;
}
}