Expressions

- Arguments::categorize is now functioning as designed.
This commit is contained in:
Paul Beckingham 2011-06-11 17:12:11 -04:00
parent a9b942e913
commit 94fa671522

View file

@ -233,7 +233,7 @@ void Arguments::categorize ()
arg->second = "rc"; arg->second = "rc";
} }
// rc.<name>[:=]<value> // rc.<name>:<value>
else if (arg->first.substr (0, 3) == "rc.") else if (arg->first.substr (0, 3) == "rc.")
{ {
found_non_sequence = true; found_non_sequence = true;
@ -281,7 +281,7 @@ void Arguments::categorize ()
arg->second = "tag"; arg->second = "tag";
} }
// <name>.<modifier>[:=]<value> // <name>.<modifier>:<value>
else if (is_attmod (arg->first)) else if (is_attmod (arg->first))
{ {
found_non_sequence = true; found_non_sequence = true;
@ -291,7 +291,7 @@ void Arguments::categorize ()
arg->second = "attmod"; arg->second = "attmod";
} }
// <name>[:=]<value> // <name>:<value>
else if (is_attr (arg->first)) else if (is_attr (arg->first))
{ {
found_non_sequence = true; found_non_sequence = true;
@ -427,7 +427,7 @@ void Arguments::rc_override (
else else
home = "."; home = ".";
context.header ("Using alternate .taskrc file " + rc.data); // TODO i18n context.header ("Using alternate .taskrc file " + rc.data);
// Keep scanning, because if there are multiple rc:file arguments, we // Keep scanning, because if there are multiple rc:file arguments, we
// want the last one to dominate. // want the last one to dominate.
@ -449,10 +449,10 @@ void Arguments::get_data_location (std::string& data)
if (arg->second == "override") if (arg->second == "override")
{ {
if (arg->first.substr (0, 16) == "rc.data.location" && if (arg->first.substr (0, 16) == "rc.data.location" &&
(arg->first[16] == ':' || arg->first[16] == '=')) arg->first[16] == ':')
{ {
data = arg->first.substr (17); data = arg->first.substr (17);
context.header ("Using alternate data.location " + data); // TODO i18n context.header ("Using alternate data.location " + data);
} }
} }
@ -474,14 +474,14 @@ void Arguments::apply_overrides ()
std::string name; std::string name;
std::string value; std::string value;
Nibbler n (arg->first); Nibbler n (arg->first);
if (n.getLiteral ("rc.") && // rc. if (n.getLiteral ("rc.") && // rc.
n.getUntilOneOf (":=", name) && // xxx n.getUntil (':', name) && // xxx
n.skipN (1)) // : n.skip (':')) // :
{ {
n.getUntilEOS (value); // May be blank. n.getUntilEOS (value); // May be blank.
context.config.set (name, value); context.config.set (name, value);
context.footnote ("Configuration override rc." + name + "=" + value); context.footnote ("Configuration override rc." + name + ":" + value);
} }
else else
context.footnote ("Problem with override: " + arg->first); context.footnote ("Problem with override: " + arg->first);
@ -606,7 +606,7 @@ bool Arguments::is_command (
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// <name>[:=]['"][<value>]['"] // <name>:['"][<value>]['"]
bool Arguments::is_attr (const std::string& input) bool Arguments::is_attr (const std::string& input)
{ {
Nibbler n (input); Nibbler n (input);
@ -621,8 +621,7 @@ bool Arguments::is_attr (const std::string& input)
if (name.find_first_of (non_word_chars) != std::string::npos) if (name.find_first_of (non_word_chars) != std::string::npos)
return false; return false;
if (n.skip (':') || if (n.skip (':'))
n.skip ('='))
{ {
// Exclude certain URLs, that look like attrs. // Exclude certain URLs, that look like attrs.
if (input.find ('@') <= n.cursor () || if (input.find ('@') <= n.cursor () ||
@ -647,7 +646,7 @@ bool Arguments::is_attr (const std::string& input)
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// <name>.<mod>[:=]['"]<value>['"] // <name>.<mod>:['"]<value>['"]
bool Arguments::is_attmod (const std::string& input) bool Arguments::is_attmod (const std::string& input)
{ {
Nibbler n (input); Nibbler n (input);
@ -666,14 +665,13 @@ bool Arguments::is_attmod (const std::string& input)
if (n.skip ('.')) if (n.skip ('.'))
{ {
n.skip ('~'); n.skip ('~');
n.getUntilOneOf (":=", modifier); n.getUntil (':', modifier);
if (modifier.length () == 0) if (modifier.length () == 0)
return false; return false;
} }
if (n.skip (':') || if (n.skip (':'))
n.skip ('='))
{ {
// Exclude certain URLs, that look like attrs. // Exclude certain URLs, that look like attrs.
if (input.find ('@') <= n.cursor () || if (input.find ('@') <= n.cursor () ||
@ -688,6 +686,8 @@ bool Arguments::is_attmod (const std::string& input)
n.getUntilEOS (value) || n.getUntilEOS (value) ||
n.depleted ()) n.depleted ())
{ {
return ! is_expression (value);
// TODO Validate and expand attribute name // TODO Validate and expand attribute name
// TODO Validate and expand modifier name // TODO Validate and expand modifier name
return true; return true;
@ -700,6 +700,12 @@ bool Arguments::is_attmod (const std::string& input)
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// /<from>/<to>/[g] // /<from>/<to>/[g]
//
// Note: one problem with this is that substitutions start with a /, and so any
// two-directory absolute path, (or three-level, if the third directory is
// named 'g') can be misinterpreted. To help (but not solve) this, if a
// substition exists on the local disk, it is not considered a subst.
// This needs to be changed to a better solution.
bool Arguments::is_subst (const std::string& input) bool Arguments::is_subst (const std::string& input)
{ {
std::string from; std::string from;
@ -841,16 +847,26 @@ bool Arguments::is_operator (
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
bool Arguments::is_expression (const std::string& input) bool Arguments::is_expression (const std::string& input)
{ {
Lexer lexer (unquoteText (input)); std::string unquoted = unquoteText (input);
// Look for space-separated operators.
std::vector <std::string> tokens;
split (tokens, unquoted, ' ');
std::vector <std::string>::iterator token;
for (token = tokens.begin (); token != tokens.end (); ++token)
if (is_operator (*token))
return true;
// Look for cuddled operators.
Lexer lexer (unquoted);
lexer.skipWhitespace (true); lexer.skipWhitespace (true);
lexer.coalesceAlpha (true); lexer.coalesceAlpha (true);
lexer.coalesceDigits (true); lexer.coalesceDigits (true);
lexer.coalesceQuoted (true); lexer.coalesceQuoted (true);
std::vector <std::string> tokens; tokens.clear ();
lexer.tokenize (tokens); lexer.tokenize (tokens);
std::vector <std::string>::iterator token;
for (token = tokens.begin (); token != tokens.end (); ++token) for (token = tokens.begin (); token != tokens.end (); ++token)
if (is_operator (*token)) if (is_operator (*token))
return true; return true;
@ -859,7 +875,7 @@ bool Arguments::is_expression (const std::string& input)
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// <name>[:=]['"]<value>['"] // <name>:['"]<value>['"]
bool Arguments::extract_attr ( bool Arguments::extract_attr (
const std::string& input, const std::string& input,
std::string& name, std::string& name,
@ -871,13 +887,12 @@ bool Arguments::extract_attr (
name = ""; name = "";
value = ""; value = "";
if (n.getUntilOneOf ("=:", name)) if (n.getUntil (':', name))
{ {
if (name.length () == 0) if (name.length () == 0)
throw std::string ("Missing attribute name"); // TODO i18n throw std::string ("Missing attribute name");
if (n.skip (':') || if (n.skip (':'))
n.skip ('='))
{ {
// Both quoted and unquoted Att's are accepted. // Both quoted and unquoted Att's are accepted.
// Consider removing this for a stricter parse. // Consider removing this for a stricter parse.
@ -888,16 +903,16 @@ bool Arguments::extract_attr (
} }
} }
else else
throw std::string ("Missing : after attribute name."); // TODO i18n throw std::string ("Missing : after attribute name.");
} }
else else
throw std::string ("Missing : after attribute name."); // TODO i18n throw std::string ("Missing : after attribute name.");
return false; return false;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// <name>.<mod>[:=]['"]<value>['"] // <name>.<mod>:['"]<value>['"]
bool Arguments::extract_attmod ( bool Arguments::extract_attmod (
const std::string& input, const std::string& input,
std::string& name, std::string& name,
@ -916,26 +931,25 @@ bool Arguments::extract_attmod (
if (n.getUntil (".", name)) if (n.getUntil (".", name))
{ {
if (name.length () == 0) if (name.length () == 0)
throw std::string ("Missing attribute name"); // TODO i18n throw std::string ("Missing attribute name");
if (n.skip ('.')) if (n.skip ('.'))
{ {
if (n.skip ('~')) if (n.skip ('~'))
sense = "negative"; sense = "negative";
if (n.getUntilOneOf (":=", modifier)) if (n.getUntil (':', modifier))
{ {
if (!Arguments::valid_modifier (modifier)) if (!Arguments::valid_modifier (modifier))
throw std::string ("The name '") + modifier + "' is not a valid modifier."; // TODO i18n throw std::string ("The name '") + modifier + "' is not a valid modifier.";
} }
else else
throw std::string ("Missing . or : after modifier."); // TODO i18n throw std::string ("Missing . or : after modifier.");
} }
else else
throw std::string ("Missing modifier."); // TODO i18n throw std::string ("Missing modifier.");
if (n.skip (':') || if (n.skip (':'))
n.skip ('='))
{ {
// Both quoted and unquoted Att's are accepted. // Both quoted and unquoted Att's are accepted.
// Consider removing this for a stricter parse. // Consider removing this for a stricter parse.
@ -946,10 +960,10 @@ bool Arguments::extract_attmod (
} }
} }
else else
throw std::string ("Missing : after attribute name."); // TODO i18n throw std::string ("Missing : after attribute name.");
} }
else else
throw std::string ("Missing : after attribute name."); // TODO i18n throw std::string ("Missing : after attribute name.");
return false; return false;
} }