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; return false;
} }
#ifdef NOPE
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Add a pair for every word from std::cin, with a category of "". // Add a pair for every word from std::cin, with a category of "".
void A3::append_stdin () void A3::append_stdin ()
{ {
bool something_happened = false;
// Use 'select' to determine whether there is any std::cin content buffered // Use 'select' to determine whether there is any std::cin content buffered
// before trying to read it, to prevent blocking. // before trying to read it, to prevent blocking.
struct timeval tv; struct timeval tv;
@ -273,13 +263,9 @@ void A3::append_stdin ()
if (arg == "--") if (arg == "--")
break; break;
this->push_back (Arg (arg, "", "")); this->push_back (Arg (arg, ""));
something_happened = true;
} }
} }
if (something_happened)
categorize ();
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -291,9 +277,9 @@ void A3::rc_override (
std::vector <Arg>::iterator arg; std::vector <Arg>::iterator arg;
for (arg = this->begin (); arg != this->end (); ++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; home = rc;
std::string::size_type last_slash = rc.data.rfind ("/"); 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); 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. // want the last one to dominate.
} }
} }
@ -321,46 +307,18 @@ void A3::get_data_location (std::string& data)
std::vector <Arg>::iterator arg; std::vector <Arg>::iterator arg;
for (arg = this->begin (); arg != this->end (); ++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" && if (arg->_raw.substr (0, 16) == "rc.data.location" &&
arg->_first[16] == ':') (arg->_raw[16] == ':' || arg->_raw[16] == '='))
{ {
data = arg->_first.substr (17); data = arg->_raw.substr (17);
context.header ("Using alternate data.location " + data); context.header ("Using alternate data.location " + data);
} }
} }
// Keep scanning, because if there are multiple rc:file arguments, we // Keep scanning, because if there are multiple overrides, we want the last
// want the last one to dominate. // 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);
}
} }
} }
@ -380,18 +338,18 @@ void A3::resolve_aliases ()
for (arg = this->begin (); arg != this->end (); ++arg) for (arg = this->begin (); arg != this->end (); ++arg)
{ {
std::map <std::string, std::string>::iterator match = std::map <std::string, std::string>::iterator match =
context.aliases.find (arg->_first); context.aliases.find (arg->_raw);
if (match != context.aliases.end ()) if (match != context.aliases.end ())
{ {
context.debug (std::string ("A3::resolve_aliases '") context.debug (std::string ("A3::resolve_aliases '")
+ arg->_first + arg->_raw
+ "' --> '" + "' --> '"
+ context.aliases[arg->_first] + context.aliases[arg->_raw]
+ "'"); + "'");
std::vector <std::string> words; std::vector <std::string> words;
splitq (words, context.aliases[arg->_first], ' '); splitq (words, context.aliases[arg->_raw], ' ');
std::vector <std::string>::iterator word; std::vector <std::string>::iterator word;
for (word = words.begin (); word != words.end (); ++word) for (word = words.begin (); word != words.end (); ++word)
@ -400,7 +358,7 @@ void A3::resolve_aliases ()
something = true; something = true;
} }
else else
expanded.push_back (arg->_first); expanded.push_back (arg->_raw);
} }
// Only overwrite if something happened. // Only overwrite if something happened.
@ -409,13 +367,43 @@ void A3::resolve_aliases ()
this->clear (); this->clear ();
std::vector <std::string>::iterator e; std::vector <std::string>::iterator e;
for (e = expanded.begin (); e != expanded.end (); ++e) for (e = expanded.begin (); e != expanded.end (); ++e)
this->push_back (Arg (*e, "", "")); this->push_back (Arg (*e, ""));
expanded.clear (); expanded.clear ();
categorize ();
} }
} }
while (something && --safety_valve > 0); 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; std::vector <Arg>::iterator arg;
for (arg = this->begin (); arg != this->end (); ++arg) for (arg = this->begin (); arg != this->end (); ++arg)
{ {
if (arg->_third == "command") if (arg->_category == "command")
found_command = true; found_command = true;
else if (arg->_third == "id" || /* TODO no "id" or "uuid" categories exist at this time. Hmm.
arg->_third == "uuid") else if (arg->_category == "id" ||
arg->_category == "uuid")
found_sequence = true; found_sequence = true;
*/
else if (arg->_third != "program" && else if (arg->_category != "program" &&
arg->_third != "override" && arg->_category != "override" &&
arg->_third != "rc") arg->_category != "rc")
found_other = true; 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 <std::string> all;
std::vector <Arg>::iterator arg; std::vector <Arg>::const_iterator arg;
for (arg = this->begin (); arg != this->end (); ++arg) for (arg = this->begin (); arg != this->end (); ++arg)
all.push_back (arg->_first); all.push_back (arg->_raw);
return all; return all;
} }
#ifdef NOPE
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
std::vector <std::string> A3::operator_list () std::vector <std::string> A3::operator_list ()
{ {
@ -498,23 +519,6 @@ std::vector <std::string> A3::operator_list ()
return all; 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) bool A3::find_command (std::string& command)
{ {

View file

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