Dependencies

- Fixed bug in Task::addDependency where a 'dup dep' error string was not
  properly composed, which cause the error message to be shown as 'k'.
- Relocated expression evaluation on modification to only be processed for
  date attributes.  This impacts DOM, but fixes more than it breaks.
- Corrected unit test that was expecting an old-style error message.
- Added protection against array overrun in next_mod_group.  Again.
This commit is contained in:
Paul Beckingham 2011-09-12 23:53:46 -04:00
parent d1e52c05d6
commit 776bfea402
3 changed files with 21 additions and 18 deletions

View file

@ -711,19 +711,20 @@ void Task::addDependency (int id)
if (id == this->id)
throw std::string (STRING_TASK_DEPEND_ITSELF);
// Check for extant dependency.
// Check that id is resolvable.
std::string uuid = context.tdb2.pending.uuid (id);
if (uuid == "")
throw format (STRING_TASK_DEPEND_MISSING, id);
// Store the dependency.
std::string depends = get ("depends");
if (depends.length ())
if (depends != "")
{
// Check for extant dependency.
if (depends.find (uuid) == std::string::npos)
set ("depends", depends + "," + uuid);
else
throw std::string (STRING_TASK_DEPEND_DUP, this->id, id);
throw format (STRING_TASK_DEPEND_DUP, this->id, id);
}
else
set ("depends", uuid);

View file

@ -426,21 +426,13 @@ void Command::modify_task (
A3::extract_attr (arg._raw, name, value);
if (A3::is_attribute (name, name)) // Canonicalize
{
// std::cout << "# Command::modify_task name='" << name << "' value='" << value << "'\n";
//std::cout << "# Command::modify_task name='" << name << "' value='" << value << "'\n";
// Get the column info.
Column* column = context.columns[name];
// All values must be eval'd first.
A3 value_tokens;
value_tokens.capture (value);
value_tokens = value_tokens.postfix (value_tokens.tokenize (value_tokens));
E9 e (value_tokens);
std::string result = e.evalExpression (task);
context.debug (std::string ("Eval '") + value + "' --> '" + result + "'");
if (result == "")
if (value == "")
{
task.remove (name);
}
@ -451,7 +443,7 @@ void Command::modify_task (
{
// Convert ID to UUID.
std::vector <std::string> deps;
split (deps, result, ',');
split (deps, value, ',');
// Apply or remove dendencies in turn.
std::vector <std::string>::iterator i;
@ -468,6 +460,15 @@ void Command::modify_task (
// Dates are special, maybe.
else if (column->type () == "date")
{
// All values must be eval'd first.
A3 value_tokens;
value_tokens.capture (value);
value_tokens = value_tokens.postfix (value_tokens.tokenize (value_tokens));
E9 e (value_tokens);
std::string result = e.evalExpression (task);
context.debug (std::string ("Eval '") + value + "' --> '" + result + "'");
// If the date value is less than 5 years, it is a duration, not a
// date, therefore add 'now'.
long l = strtol (result.c_str (), NULL, 10);
@ -483,7 +484,7 @@ void Command::modify_task (
// By default, just add/remove it.
else
task.set (name, result);
task.set (name, value);
// Warn about deprecated/obsolete attribute usage.
legacyAttributeCheck (name);
@ -572,8 +573,9 @@ bool Command::next_mod_group (const A3& input, Arg& arg, unsigned int& pos)
else if (arg._raw == "depends")
{
while (input[pos]._category == Arg::cat_op ||
input[pos]._type == Arg::type_number)
while (pos < input.size () &&
(input[pos]._category == Arg::cat_op ||
input[pos]._type == Arg::type_number))
{
arg._raw += input[pos++]._raw;
}