C++11: Cleaned up program framework with range-based for
This commit is contained in:
502
src/CLI.cpp
502
src/CLI.cpp
File diff suppressed because it is too large
Load Diff
@@ -119,10 +119,9 @@ Color::Color (const std::string& spec)
|
|||||||
bool bg = false;
|
bool bg = false;
|
||||||
int index;
|
int index;
|
||||||
std::string word;
|
std::string word;
|
||||||
std::vector <std::string>::iterator it;
|
for (auto& it : words)
|
||||||
for (it = words.begin (); it != words.end (); ++it)
|
|
||||||
{
|
{
|
||||||
word = lowerCase (trim (*it));
|
word = lowerCase (trim (it));
|
||||||
|
|
||||||
if (word == "bold") fg_value |= _COLOR_BOLD;
|
if (word == "bold") fg_value |= _COLOR_BOLD;
|
||||||
else if (word == "bright") bg_value |= _COLOR_BRIGHT;
|
else if (word == "bright") bg_value |= _COLOR_BRIGHT;
|
||||||
@@ -154,7 +153,7 @@ Color::Color (const std::string& spec)
|
|||||||
{
|
{
|
||||||
index = atoi (word.substr (4).c_str ());
|
index = atoi (word.substr (4).c_str ());
|
||||||
if (index < 0 || index > 23)
|
if (index < 0 || index > 23)
|
||||||
throw format (STRING_COLOR_UNRECOGNIZED, *it);
|
throw format (STRING_COLOR_UNRECOGNIZED, it);
|
||||||
|
|
||||||
if (bg)
|
if (bg)
|
||||||
{
|
{
|
||||||
@@ -176,7 +175,7 @@ Color::Color (const std::string& spec)
|
|||||||
index = atoi (word.substr (3).c_str ());
|
index = atoi (word.substr (3).c_str ());
|
||||||
if (word.length () != 6 ||
|
if (word.length () != 6 ||
|
||||||
index < 0 || index > 555)
|
index < 0 || index > 555)
|
||||||
throw format (STRING_COLOR_UNRECOGNIZED, *it);
|
throw format (STRING_COLOR_UNRECOGNIZED, it);
|
||||||
|
|
||||||
int r = atoi (word.substr (3, 1).c_str ());
|
int r = atoi (word.substr (3, 1).c_str ());
|
||||||
int g = atoi (word.substr (4, 1).c_str ());
|
int g = atoi (word.substr (4, 1).c_str ());
|
||||||
@@ -184,7 +183,7 @@ Color::Color (const std::string& spec)
|
|||||||
if (r < 0 || r > 5 ||
|
if (r < 0 || r > 5 ||
|
||||||
g < 0 || g > 5 ||
|
g < 0 || g > 5 ||
|
||||||
b < 0 || b > 5)
|
b < 0 || b > 5)
|
||||||
throw format (STRING_COLOR_UNRECOGNIZED, *it);
|
throw format (STRING_COLOR_UNRECOGNIZED, it);
|
||||||
|
|
||||||
index = 16 + r*36 + g*6 + b;
|
index = 16 + r*36 + g*6 + b;
|
||||||
|
|
||||||
@@ -207,7 +206,7 @@ Color::Color (const std::string& spec)
|
|||||||
{
|
{
|
||||||
index = atoi (word.substr (5).c_str ());
|
index = atoi (word.substr (5).c_str ());
|
||||||
if (index < 0 || index > 255)
|
if (index < 0 || index > 255)
|
||||||
throw format (STRING_COLOR_UNRECOGNIZED, *it);
|
throw format (STRING_COLOR_UNRECOGNIZED, it);
|
||||||
|
|
||||||
upgrade ();
|
upgrade ();
|
||||||
|
|
||||||
@@ -225,7 +224,7 @@ Color::Color (const std::string& spec)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (word != "")
|
else if (word != "")
|
||||||
throw format (STRING_COLOR_UNRECOGNIZED, *it);
|
throw format (STRING_COLOR_UNRECOGNIZED, it);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now combine the fg and bg into a single color.
|
// Now combine the fg and bg into a single color.
|
||||||
|
|||||||
@@ -528,11 +528,8 @@ void Config::parse (const std::string& input, int nest /* = 1 */)
|
|||||||
split (lines, input, "\n");
|
split (lines, input, "\n");
|
||||||
|
|
||||||
// Parse each line.
|
// Parse each line.
|
||||||
std::vector <std::string>::iterator it;
|
for (auto& line : lines)
|
||||||
for (it = lines.begin (); it != lines.end (); ++it)
|
|
||||||
{
|
{
|
||||||
std::string line = *it;
|
|
||||||
|
|
||||||
// Remove comments.
|
// Remove comments.
|
||||||
std::string::size_type pound = line.find ("#"); // no i18n
|
std::string::size_type pound = line.find ("#"); // no i18n
|
||||||
if (pound != std::string::npos)
|
if (pound != std::string::npos)
|
||||||
@@ -714,9 +711,8 @@ void Config::set (const std::string& key, const std::string& value)
|
|||||||
// Provide a vector of all configuration keys.
|
// Provide a vector of all configuration keys.
|
||||||
void Config::all (std::vector<std::string>& items) const
|
void Config::all (std::vector<std::string>& items) const
|
||||||
{
|
{
|
||||||
std::map <std::string, std::string>::const_iterator it;
|
for (auto& it : *this)
|
||||||
for (it = this->begin (); it != this->end (); ++it)
|
items.push_back (it.first);
|
||||||
items.push_back (it->first);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|||||||
162
src/Context.cpp
162
src/Context.cpp
@@ -84,13 +84,11 @@ Context::Context ()
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
Context::~Context ()
|
Context::~Context ()
|
||||||
{
|
{
|
||||||
std::map<std::string, Command*>::iterator com;
|
for (auto& com : commands)
|
||||||
for (com = commands.begin (); com != commands.end (); ++com)
|
delete com.second;
|
||||||
delete com->second;
|
|
||||||
|
|
||||||
std::map<std::string, Column*>::iterator col;
|
for (auto& col : columns)
|
||||||
for (col = columns.begin (); col != columns.end (); ++col)
|
delete col.second;
|
||||||
delete col->second;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -156,14 +154,13 @@ int Context::initialize (int argc, const char** argv)
|
|||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
Command::factory (commands);
|
Command::factory (commands);
|
||||||
std::map <std::string, Command*>::iterator cmd;
|
for (auto& cmd : commands)
|
||||||
for (cmd = commands.begin (); cmd != commands.end (); ++cmd)
|
|
||||||
{
|
{
|
||||||
cli.entity ("cmd", cmd->first);
|
cli.entity ("cmd", cmd.first);
|
||||||
cli.entity ((cmd->second->read_only () ? "readcmd" : "writecmd"), cmd->first);
|
cli.entity ((cmd.second->read_only () ? "readcmd" : "writecmd"), cmd.first);
|
||||||
|
|
||||||
if (cmd->first[0] == '_')
|
if (cmd.first[0] == '_')
|
||||||
cli.entity ("helper", cmd->first);
|
cli.entity ("helper", cmd.first);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -173,9 +170,8 @@ int Context::initialize (int argc, const char** argv)
|
|||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
Column::factory (columns);
|
Column::factory (columns);
|
||||||
std::map <std::string, Column*>::iterator col;
|
for (auto& col : columns)
|
||||||
for (col = columns.begin (); col != columns.end (); ++col)
|
cli.entity ("attribute", col.first);
|
||||||
cli.entity ("attribute", col->first);
|
|
||||||
|
|
||||||
cli.entity ("pseudo", "limit");
|
cli.entity ("pseudo", "limit");
|
||||||
|
|
||||||
@@ -188,15 +184,11 @@ int Context::initialize (int argc, const char** argv)
|
|||||||
for (unsigned int i = 0; i < NUM_MODIFIER_NAMES; ++i)
|
for (unsigned int i = 0; i < NUM_MODIFIER_NAMES; ++i)
|
||||||
cli.entity ("modifier", modifierNames[i]);
|
cli.entity ("modifier", modifierNames[i]);
|
||||||
|
|
||||||
std::vector <std::string> operators;
|
for (auto& op : Eval::getOperators ())
|
||||||
Eval::getOperators (operators);
|
cli.entity ("operator", op);
|
||||||
std::vector <std::string>::iterator op;
|
|
||||||
for (op = operators.begin (); op != operators.end (); ++op)
|
|
||||||
cli.entity ("operator", *op);
|
|
||||||
|
|
||||||
Eval::getBinaryOperators (operators);
|
for (auto& op : Eval::getBinaryOperators ())
|
||||||
for (op = operators.begin (); op != operators.end (); ++op)
|
cli.entity ("binary_operator", op);
|
||||||
cli.entity ("binary_operator", *op);
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
@@ -223,21 +215,20 @@ int Context::initialize (int argc, const char** argv)
|
|||||||
bool foundDefault = false;
|
bool foundDefault = false;
|
||||||
bool foundAssumed = false;
|
bool foundAssumed = false;
|
||||||
std::string combined;
|
std::string combined;
|
||||||
std::vector <A>::const_iterator a;
|
for (auto& a : cli._args)
|
||||||
for (a = cli._args.begin (); a != cli._args.end (); ++a)
|
|
||||||
{
|
{
|
||||||
if (combined.length ())
|
if (combined.length ())
|
||||||
combined += ' ';
|
combined += ' ';
|
||||||
|
|
||||||
if (a->attribute ("canonical") != "")
|
if (a.attribute ("canonical") != "")
|
||||||
combined += a->attribute ("canonical");
|
combined += a.attribute ("canonical");
|
||||||
else
|
else
|
||||||
combined += a->attribute ("raw");
|
combined += a.attribute ("raw");
|
||||||
|
|
||||||
if (a->hasTag ("DEFAULT"))
|
if (a.hasTag ("DEFAULT"))
|
||||||
foundDefault = true;
|
foundDefault = true;
|
||||||
|
|
||||||
if (a->hasTag ("ASSUMED"))
|
if (a.hasTag ("ASSUMED"))
|
||||||
foundAssumed = true;
|
foundAssumed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -280,44 +271,40 @@ int Context::initialize (int argc, const char** argv)
|
|||||||
// Dump all debug messages, controlled by rc.debug.
|
// Dump all debug messages, controlled by rc.debug.
|
||||||
if (config.getBoolean ("debug"))
|
if (config.getBoolean ("debug"))
|
||||||
{
|
{
|
||||||
std::vector <std::string>::iterator d;
|
for (auto& d : debugMessages)
|
||||||
for (d = debugMessages.begin (); d != debugMessages.end (); ++d)
|
|
||||||
if (color ())
|
if (color ())
|
||||||
std::cerr << colorizeDebug (*d) << "\n";
|
std::cerr << colorizeDebug (d) << "\n";
|
||||||
else
|
else
|
||||||
std::cerr << *d << "\n";
|
std::cerr << d << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dump all headers, controlled by 'header' verbosity token.
|
// Dump all headers, controlled by 'header' verbosity token.
|
||||||
if (verbose ("header"))
|
if (verbose ("header"))
|
||||||
{
|
{
|
||||||
std::vector <std::string>::iterator h;
|
for (auto& h : headers)
|
||||||
for (h = headers.begin (); h != headers.end (); ++h)
|
|
||||||
if (color ())
|
if (color ())
|
||||||
std::cerr << colorizeHeader (*h) << "\n";
|
std::cerr << colorizeHeader (h) << "\n";
|
||||||
else
|
else
|
||||||
std::cerr << *h << "\n";
|
std::cerr << h << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dump all footnotes, controlled by 'footnote' verbosity token.
|
// Dump all footnotes, controlled by 'footnote' verbosity token.
|
||||||
if (verbose ("footnote"))
|
if (verbose ("footnote"))
|
||||||
{
|
{
|
||||||
std::vector <std::string>::iterator f;
|
for (auto& f : footnotes)
|
||||||
for (f = footnotes.begin (); f != footnotes.end (); ++f)
|
|
||||||
if (color ())
|
if (color ())
|
||||||
std::cerr << colorizeFootnote (*f) << "\n";
|
std::cerr << colorizeFootnote (f) << "\n";
|
||||||
else
|
else
|
||||||
std::cerr << *f << "\n";
|
std::cerr << f << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dump all errors, non-maskable.
|
// Dump all errors, non-maskable.
|
||||||
// Colorized as footnotes.
|
// Colorized as footnotes.
|
||||||
std::vector <std::string>::iterator e;
|
for (auto& e : errors)
|
||||||
for (e = errors.begin (); e != errors.end (); ++e)
|
|
||||||
if (color ())
|
if (color ())
|
||||||
std::cerr << colorizeFootnote (*e) << "\n";
|
std::cerr << colorizeFootnote (e) << "\n";
|
||||||
else
|
else
|
||||||
std::cerr << *e << "\n";
|
std::cerr << e << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
timer_init.stop ();
|
timer_init.stop ();
|
||||||
@@ -390,23 +377,21 @@ int Context::run ()
|
|||||||
// Dump all debug messages, controlled by rc.debug.
|
// Dump all debug messages, controlled by rc.debug.
|
||||||
if (config.getBoolean ("debug"))
|
if (config.getBoolean ("debug"))
|
||||||
{
|
{
|
||||||
std::vector <std::string>::iterator d;
|
for (auto& d : debugMessages)
|
||||||
for (d = debugMessages.begin (); d != debugMessages.end (); ++d)
|
|
||||||
if (color ())
|
if (color ())
|
||||||
std::cerr << colorizeDebug (*d) << "\n";
|
std::cerr << colorizeDebug (d) << "\n";
|
||||||
else
|
else
|
||||||
std::cerr << *d << "\n";
|
std::cerr << d << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dump all headers, controlled by 'header' verbosity token.
|
// Dump all headers, controlled by 'header' verbosity token.
|
||||||
if (verbose ("header"))
|
if (verbose ("header"))
|
||||||
{
|
{
|
||||||
std::vector <std::string>::iterator h;
|
for (auto& h : headers)
|
||||||
for (h = headers.begin (); h != headers.end (); ++h)
|
|
||||||
if (color ())
|
if (color ())
|
||||||
std::cerr << colorizeHeader (*h) << "\n";
|
std::cerr << colorizeHeader (h) << "\n";
|
||||||
else
|
else
|
||||||
std::cerr << *h << "\n";
|
std::cerr << h << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dump the report output.
|
// Dump the report output.
|
||||||
@@ -415,22 +400,20 @@ int Context::run ()
|
|||||||
// Dump all footnotes, controlled by 'footnote' verbosity token.
|
// Dump all footnotes, controlled by 'footnote' verbosity token.
|
||||||
if (verbose ("footnote"))
|
if (verbose ("footnote"))
|
||||||
{
|
{
|
||||||
std::vector <std::string>::iterator f;
|
for (auto& f : footnotes)
|
||||||
for (f = footnotes.begin (); f != footnotes.end (); ++f)
|
|
||||||
if (color ())
|
if (color ())
|
||||||
std::cerr << colorizeFootnote (*f) << "\n";
|
std::cerr << colorizeFootnote (f) << "\n";
|
||||||
else
|
else
|
||||||
std::cerr << *f << "\n";
|
std::cerr << f << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dump all errors, non-maskable.
|
// Dump all errors, non-maskable.
|
||||||
// Colorized as footnotes.
|
// Colorized as footnotes.
|
||||||
std::vector <std::string>::iterator e;
|
for (auto& e : errors)
|
||||||
for (e = errors.begin (); e != errors.end (); ++e)
|
|
||||||
if (color ())
|
if (color ())
|
||||||
std::cerr << colorizeError (*e) << "\n";
|
std::cerr << colorizeError (e) << "\n";
|
||||||
else
|
else
|
||||||
std::cerr << *e << "\n";
|
std::cerr << e << "\n";
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@@ -581,9 +564,8 @@ bool Context::verbose (const std::string& token)
|
|||||||
const std::vector <std::string> Context::getColumns () const
|
const std::vector <std::string> Context::getColumns () const
|
||||||
{
|
{
|
||||||
std::vector <std::string> output;
|
std::vector <std::string> output;
|
||||||
std::map <std::string, Column*>::const_iterator i;
|
for (auto& col : columns)
|
||||||
for (i = columns.begin (); i != columns.end (); ++i)
|
output.push_back (col.first);
|
||||||
output.push_back (i->first);
|
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
@@ -592,9 +574,8 @@ const std::vector <std::string> Context::getColumns () const
|
|||||||
const std::vector <std::string> Context::getCommands () const
|
const std::vector <std::string> Context::getCommands () const
|
||||||
{
|
{
|
||||||
std::vector <std::string> output;
|
std::vector <std::string> output;
|
||||||
std::map <std::string, Command*>::const_iterator i;
|
for (auto& cmd : commands)
|
||||||
for (i = commands.begin (); i != commands.end (); ++i)
|
output.push_back (cmd.first);
|
||||||
output.push_back (i->first);
|
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
@@ -640,24 +621,22 @@ void Context::staticInitialization ()
|
|||||||
Lexer::dateFormat = Variant::dateFormat = config.get ("dateformat");
|
Lexer::dateFormat = Variant::dateFormat = config.get ("dateformat");
|
||||||
Lexer::isoEnabled = Variant::isoEnabled = config.getBoolean ("date.iso");
|
Lexer::isoEnabled = Variant::isoEnabled = config.getBoolean ("date.iso");
|
||||||
|
|
||||||
Config::const_iterator rc;
|
for (auto& rc : config)
|
||||||
for (rc = config.begin (); rc != config.end (); ++rc)
|
|
||||||
{
|
{
|
||||||
if (rc->first.substr (0, 4) == "uda." &&
|
if (rc.first.substr (0, 4) == "uda." &&
|
||||||
rc->first.substr (rc->first.length () - 7, 7) == ".values")
|
rc.first.substr (rc.first.length () - 7, 7) == ".values")
|
||||||
{
|
{
|
||||||
std::string name = rc->first.substr (4, rc->first.length () - 7 - 4);
|
std::string name = rc.first.substr (4, rc.first.length () - 7 - 4);
|
||||||
std::vector <std::string> values;
|
std::vector <std::string> values;
|
||||||
split (values, rc->second, ',');
|
split (values, rc.second, ',');
|
||||||
|
|
||||||
for (auto r = values.rbegin(); r != values.rend (); ++r)
|
for (auto r = values.rbegin(); r != values.rend (); ++r)
|
||||||
Task::customOrder[name].push_back (*r);
|
Task::customOrder[name].push_back (*r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map <std::string, Column*>::iterator i;
|
for (auto& col : columns)
|
||||||
for (i = columns.begin (); i != columns.end (); ++i)
|
Task::attributes[col.first] = col.second->type ();
|
||||||
Task::attributes[i->first] = i->second->type ();
|
|
||||||
|
|
||||||
Task::urgencyProjectCoefficient = config.getReal ("urgency.project.coefficient");
|
Task::urgencyProjectCoefficient = config.getReal ("urgency.project.coefficient");
|
||||||
Task::urgencyActiveCoefficient = config.getReal ("urgency.active.coefficient");
|
Task::urgencyActiveCoefficient = config.getReal ("urgency.active.coefficient");
|
||||||
@@ -676,11 +655,10 @@ void Context::staticInitialization ()
|
|||||||
// Tag- and project-specific coefficients.
|
// Tag- and project-specific coefficients.
|
||||||
std::vector <std::string> all;
|
std::vector <std::string> all;
|
||||||
config.all (all);
|
config.all (all);
|
||||||
std::vector <std::string>::iterator var;
|
for (auto& var : all)
|
||||||
for (var = all.begin (); var != all.end (); ++var)
|
if (var.substr (0, 13) == "urgency.user." ||
|
||||||
if (var->substr (0, 13) == "urgency.user." ||
|
var.substr (0, 12) == "urgency.uda.")
|
||||||
var->substr (0, 12) == "urgency.uda.")
|
Task::coefficients[var] = config.getReal (var);
|
||||||
Task::coefficients[*var] = config.getReal (*var);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -745,16 +723,14 @@ void Context::clear ()
|
|||||||
tdb2.clear ();
|
tdb2.clear ();
|
||||||
|
|
||||||
// Eliminate the command objects.
|
// Eliminate the command objects.
|
||||||
std::map <std::string, Command*>::iterator com;
|
for (auto& cmd : commands)
|
||||||
for (com = commands.begin (); com != commands.end (); ++com)
|
delete cmd.second;
|
||||||
delete com->second;
|
|
||||||
|
|
||||||
commands.clear ();
|
commands.clear ();
|
||||||
|
|
||||||
// Eliminate the column objects.
|
// Eliminate the column objects.
|
||||||
std::map <std::string, Column*>::iterator col;
|
for (auto& col : columns)
|
||||||
for (col = columns.begin (); col != columns.end (); ++col)
|
delete col.second;
|
||||||
delete col->second;
|
|
||||||
|
|
||||||
columns.clear ();
|
columns.clear ();
|
||||||
clearMessages ();
|
clearMessages ();
|
||||||
@@ -770,8 +746,7 @@ void Context::updateXtermTitle ()
|
|||||||
std::string command = cli.getCommand ();
|
std::string command = cli.getCommand ();
|
||||||
std::string title;
|
std::string title;
|
||||||
|
|
||||||
std::vector <A>::const_iterator a;
|
for (auto a = cli._args.begin (); a != cli._args.end (); ++a)
|
||||||
for (a = cli._args.begin (); a != cli._args.end (); ++a)
|
|
||||||
{
|
{
|
||||||
if (a != cli._args.begin ())
|
if (a != cli._args.begin ())
|
||||||
title += ' ';
|
title += ' ';
|
||||||
@@ -799,10 +774,9 @@ void Context::updateVerbosity ()
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void Context::loadAliases ()
|
void Context::loadAliases ()
|
||||||
{
|
{
|
||||||
std::map <std::string, std::string>::iterator i;
|
for (auto& i : config)
|
||||||
for (i = config.begin (); i != config.end (); ++i)
|
if (i.first.substr (0, 6) == "alias.")
|
||||||
if (i->first.substr (0, 6) == "alias.")
|
cli.alias (i.first.substr (6), i.second);
|
||||||
cli.alias (i->first.substr (6), i->second);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|||||||
14
src/DOM.cpp
14
src/DOM.cpp
@@ -88,7 +88,7 @@ bool DOM::get (const std::string& name, Variant& value)
|
|||||||
name.substr (0, 3) == "rc.")
|
name.substr (0, 3) == "rc.")
|
||||||
{
|
{
|
||||||
std::string key = name.substr (3);
|
std::string key = name.substr (3);
|
||||||
std::map <std::string, std::string>::iterator c = context.config.find (key);
|
auto c = context.config.find (key);
|
||||||
if (c != context.config.end ())
|
if (c != context.config.end ())
|
||||||
{
|
{
|
||||||
value = Variant (c->second);
|
value = Variant (c->second);
|
||||||
@@ -376,8 +376,7 @@ bool DOM::get (const std::string& name, const Task& task, Variant& value)
|
|||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
// Count off the 'a'th annotation.
|
// Count off the 'a'th annotation.
|
||||||
std::map <std::string, std::string>::iterator i;
|
for (auto& i : annos)
|
||||||
for (i = annos.begin (); i != annos.end (); ++i)
|
|
||||||
{
|
{
|
||||||
if (++count == a)
|
if (++count == a)
|
||||||
{
|
{
|
||||||
@@ -385,12 +384,12 @@ bool DOM::get (const std::string& name, const Task& task, Variant& value)
|
|||||||
{
|
{
|
||||||
// annotation_1234567890
|
// annotation_1234567890
|
||||||
// 0 ^11
|
// 0 ^11
|
||||||
value = Variant ((time_t) strtol (i->first.substr (11).c_str (), NULL, 10), Variant::type_date);
|
value = Variant ((time_t) strtol (i.first.substr (11).c_str (), NULL, 10), Variant::type_date);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (elements[3] == "description")
|
else if (elements[3] == "description")
|
||||||
{
|
{
|
||||||
value = Variant (i->second);
|
value = Variant (i.second);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -405,8 +404,7 @@ bool DOM::get (const std::string& name, const Task& task, Variant& value)
|
|||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
// Count off the 'a'th annotation.
|
// Count off the 'a'th annotation.
|
||||||
std::map <std::string, std::string>::iterator i;
|
for (auto& i : annos)
|
||||||
for (i = annos.begin (); i != annos.end (); ++i)
|
|
||||||
{
|
{
|
||||||
if (++count == a)
|
if (++count == a)
|
||||||
{
|
{
|
||||||
@@ -419,7 +417,7 @@ bool DOM::get (const std::string& name, const Task& task, Variant& value)
|
|||||||
// <annotations>.<N>.entry.hour
|
// <annotations>.<N>.entry.hour
|
||||||
// <annotations>.<N>.entry.minute
|
// <annotations>.<N>.entry.minute
|
||||||
// <annotations>.<N>.entry.second
|
// <annotations>.<N>.entry.second
|
||||||
Date date (i->first.substr (11));
|
Date date (i.first.substr (11));
|
||||||
if (elements[4] == "year") { value = Variant (static_cast<int> (date.year ())); return true; }
|
if (elements[4] == "year") { value = Variant (static_cast<int> (date.year ())); return true; }
|
||||||
else if (elements[4] == "month") { value = Variant (static_cast<int> (date.month ())); return true; }
|
else if (elements[4] == "month") { value = Variant (static_cast<int> (date.month ())); return true; }
|
||||||
else if (elements[4] == "day") { value = Variant (static_cast<int> (date.day ())); return true; }
|
else if (elements[4] == "day") { value = Variant (static_cast<int> (date.day ())); return true; }
|
||||||
|
|||||||
@@ -536,10 +536,9 @@ int Date::length (const std::string& format)
|
|||||||
{
|
{
|
||||||
int total = 0;
|
int total = 0;
|
||||||
|
|
||||||
std::string::const_iterator i;
|
for (auto& i : format)
|
||||||
for (i = format.begin (); i != format.end (); ++i)
|
|
||||||
{
|
{
|
||||||
switch (*i)
|
switch (i)
|
||||||
{
|
{
|
||||||
case 'm':
|
case 'm':
|
||||||
case 'M':
|
case 'M':
|
||||||
@@ -563,7 +562,7 @@ int Date::length (const std::string& format)
|
|||||||
case 'B': total += 10; break;
|
case 'B': total += 10; break;
|
||||||
|
|
||||||
// Calculate the width, don't assume a single character width.
|
// Calculate the width, don't assume a single character width.
|
||||||
default: total += mk_wcwidth (*i); break;
|
default: total += mk_wcwidth (i); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
127
src/Eval.cpp
127
src/Eval.cpp
@@ -217,21 +217,25 @@ void Eval::debug (bool value)
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Static.
|
// Static.
|
||||||
void Eval::getOperators (std::vector <std::string>& all)
|
std::vector <std::string> Eval::getOperators ()
|
||||||
{
|
{
|
||||||
all.clear ();
|
std::vector <std::string> all;
|
||||||
for (unsigned int i = 0; i < NUM_OPERATORS; ++i)
|
for (unsigned int i = 0; i < NUM_OPERATORS; ++i)
|
||||||
all.push_back (operators[i].op);
|
all.push_back (operators[i].op);
|
||||||
|
|
||||||
|
return all;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Static.
|
// Static.
|
||||||
void Eval::getBinaryOperators (std::vector <std::string>& all)
|
std::vector <std::string> Eval::getBinaryOperators ()
|
||||||
{
|
{
|
||||||
all.clear ();
|
std::vector <std::string> all;
|
||||||
for (unsigned int i = 0; i < NUM_OPERATORS; ++i)
|
for (unsigned int i = 0; i < NUM_OPERATORS; ++i)
|
||||||
if (operators[i].type == 'b')
|
if (operators[i].type == 'b')
|
||||||
all.push_back (operators[i].op);
|
all.push_back (operators[i].op);
|
||||||
|
|
||||||
|
return all;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -245,12 +249,11 @@ void Eval::evaluatePostfixStack (
|
|||||||
// This is stack used by the postfix evaluator.
|
// This is stack used by the postfix evaluator.
|
||||||
std::vector <Variant> values;
|
std::vector <Variant> values;
|
||||||
|
|
||||||
std::vector <std::pair <std::string, Lexer::Type>>::const_iterator token;
|
for (auto& token : tokens)
|
||||||
for (token = tokens.begin (); token != tokens.end (); ++token)
|
|
||||||
{
|
{
|
||||||
// Unary operators.
|
// Unary operators.
|
||||||
if (token->second == Lexer::Type::op &&
|
if (token.second == Lexer::Type::op &&
|
||||||
token->first == "!")
|
token.first == "!")
|
||||||
{
|
{
|
||||||
if (values.size () < 1)
|
if (values.size () < 1)
|
||||||
throw std::string (STRING_EVAL_NO_EVAL);
|
throw std::string (STRING_EVAL_NO_EVAL);
|
||||||
@@ -260,10 +263,10 @@ void Eval::evaluatePostfixStack (
|
|||||||
Variant result = ! right;
|
Variant result = ! right;
|
||||||
values.push_back (result);
|
values.push_back (result);
|
||||||
if (_debug)
|
if (_debug)
|
||||||
context.debug (format ("Eval {1} ↓'{2}' → ↑'{3}'", token->first, (std::string) right, (std::string) result));
|
context.debug (format ("Eval {1} ↓'{2}' → ↑'{3}'", token.first, (std::string) right, (std::string) result));
|
||||||
}
|
}
|
||||||
else if (token->second == Lexer::Type::op &&
|
else if (token.second == Lexer::Type::op &&
|
||||||
token->first == "_neg_")
|
token.first == "_neg_")
|
||||||
{
|
{
|
||||||
if (values.size () < 1)
|
if (values.size () < 1)
|
||||||
throw std::string (STRING_EVAL_NO_EVAL);
|
throw std::string (STRING_EVAL_NO_EVAL);
|
||||||
@@ -276,18 +279,18 @@ void Eval::evaluatePostfixStack (
|
|||||||
values.push_back (result);
|
values.push_back (result);
|
||||||
|
|
||||||
if (_debug)
|
if (_debug)
|
||||||
context.debug (format ("Eval {1} ↓'{2}' → ↑'{3}'", token->first, (std::string) right, (std::string) result));
|
context.debug (format ("Eval {1} ↓'{2}' → ↑'{3}'", token.first, (std::string) right, (std::string) result));
|
||||||
}
|
}
|
||||||
else if (token->second == Lexer::Type::op &&
|
else if (token.second == Lexer::Type::op &&
|
||||||
token->first == "_pos_")
|
token.first == "_pos_")
|
||||||
{
|
{
|
||||||
// The _pos_ operator is a NOP.
|
// The _pos_ operator is a NOP.
|
||||||
if (_debug)
|
if (_debug)
|
||||||
context.debug (format ("[{1}] eval op {2} NOP", values.size (), token->first));
|
context.debug (format ("[{1}] eval op {2} NOP", values.size (), token.first));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Binary operators.
|
// Binary operators.
|
||||||
else if (token->second == Lexer::Type::op)
|
else if (token.second == Lexer::Type::op)
|
||||||
{
|
{
|
||||||
if (values.size () < 2)
|
if (values.size () < 2)
|
||||||
throw std::string (STRING_EVAL_NO_EVAL);
|
throw std::string (STRING_EVAL_NO_EVAL);
|
||||||
@@ -300,46 +303,46 @@ void Eval::evaluatePostfixStack (
|
|||||||
|
|
||||||
// Ordering these by anticipation frequency of use is a good idea.
|
// Ordering these by anticipation frequency of use is a good idea.
|
||||||
Variant result;
|
Variant result;
|
||||||
if (token->first == "and") result = left && right;
|
if (token.first == "and") result = left && right;
|
||||||
else if (token->first == "or") result = left || right;
|
else if (token.first == "or") result = left || right;
|
||||||
else if (token->first == "&&") result = left && right;
|
else if (token.first == "&&") result = left && right;
|
||||||
else if (token->first == "||") result = left || right;
|
else if (token.first == "||") result = left || right;
|
||||||
else if (token->first == "<") result = left < right;
|
else if (token.first == "<") result = left < right;
|
||||||
else if (token->first == "<=") result = left <= right;
|
else if (token.first == "<=") result = left <= right;
|
||||||
else if (token->first == ">") result = left > right;
|
else if (token.first == ">") result = left > right;
|
||||||
else if (token->first == ">=") result = left >= right;
|
else if (token.first == ">=") result = left >= right;
|
||||||
else if (token->first == "==") result = left.operator== (right);
|
else if (token.first == "==") result = left.operator== (right);
|
||||||
else if (token->first == "!==") result = left.operator!= (right);
|
else if (token.first == "!==") result = left.operator!= (right);
|
||||||
else if (token->first == "=") result = left.operator_partial (right);
|
else if (token.first == "=") result = left.operator_partial (right);
|
||||||
else if (token->first == "!=") result = left.operator_nopartial (right);
|
else if (token.first == "!=") result = left.operator_nopartial (right);
|
||||||
else if (token->first == "+") result = left + right;
|
else if (token.first == "+") result = left + right;
|
||||||
else if (token->first == "-") result = left - right;
|
else if (token.first == "-") result = left - right;
|
||||||
else if (token->first == "*") result = left * right;
|
else if (token.first == "*") result = left * right;
|
||||||
else if (token->first == "/") result = left / right;
|
else if (token.first == "/") result = left / right;
|
||||||
else if (token->first == "^") result = left ^ right;
|
else if (token.first == "^") result = left ^ right;
|
||||||
else if (token->first == "%") result = left % right;
|
else if (token.first == "%") result = left % right;
|
||||||
else if (token->first == "xor") result = left.operator_xor (right);
|
else if (token.first == "xor") result = left.operator_xor (right);
|
||||||
else if (token->first == "~") result = left.operator_match (right, contextTask);
|
else if (token.first == "~") result = left.operator_match (right, contextTask);
|
||||||
else if (token->first == "!~") result = left.operator_nomatch (right, contextTask);
|
else if (token.first == "!~") result = left.operator_nomatch (right, contextTask);
|
||||||
else if (token->first == "_hastag_") result = left.operator_hastag (right, contextTask);
|
else if (token.first == "_hastag_") result = left.operator_hastag (right, contextTask);
|
||||||
else if (token->first == "_notag_") result = left.operator_notag (right, contextTask);
|
else if (token.first == "_notag_") result = left.operator_notag (right, contextTask);
|
||||||
else
|
else
|
||||||
throw format (STRING_EVAL_UNSUPPORTED, token->first);
|
throw format (STRING_EVAL_UNSUPPORTED, token.first);
|
||||||
|
|
||||||
values.push_back (result);
|
values.push_back (result);
|
||||||
|
|
||||||
if (_debug)
|
if (_debug)
|
||||||
context.debug (format ("Eval ↓'{1}' {2} ↓'{3}' → ↑'{4}'", (std::string) left, token->first, (std::string) right, (std::string) result));
|
context.debug (format ("Eval ↓'{1}' {2} ↓'{3}' → ↑'{4}'", (std::string) left, token.first, (std::string) right, (std::string) result));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Literals and identifiers.
|
// Literals and identifiers.
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Variant v (token->first);
|
Variant v (token.first);
|
||||||
switch (token->second)
|
switch (token.second)
|
||||||
{
|
{
|
||||||
case Lexer::Type::number:
|
case Lexer::Type::number:
|
||||||
if (Lexer::isAllDigits (token->first))
|
if (Lexer::isAllDigits (token.first))
|
||||||
{
|
{
|
||||||
v.cast (Variant::type_integer);
|
v.cast (Variant::type_integer);
|
||||||
if (_debug)
|
if (_debug)
|
||||||
@@ -362,13 +365,12 @@ void Eval::evaluatePostfixStack (
|
|||||||
case Lexer::Type::identifier:
|
case Lexer::Type::identifier:
|
||||||
{
|
{
|
||||||
bool found = false;
|
bool found = false;
|
||||||
std::vector <bool (*)(const std::string&, Variant&)>::const_iterator source;
|
for (auto source = _sources.begin (); source != _sources.end (); ++source)
|
||||||
for (source = _sources.begin (); source != _sources.end (); ++source)
|
|
||||||
{
|
{
|
||||||
if ((*source) (token->first, v))
|
if ((*source) (token.first, v))
|
||||||
{
|
{
|
||||||
if (_debug)
|
if (_debug)
|
||||||
context.debug (format ("Eval identifier source '{1}' → ↑'{2}'", token->first, (std::string) v));
|
context.debug (format ("Eval identifier source '{1}' → ↑'{2}'", token.first, (std::string) v));
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -379,7 +381,7 @@ void Eval::evaluatePostfixStack (
|
|||||||
{
|
{
|
||||||
v.cast (Variant::type_string);
|
v.cast (Variant::type_string);
|
||||||
if (_debug)
|
if (_debug)
|
||||||
context.debug (format ("Eval identifier source failed '{1}'", token->first));
|
context.debug (format ("Eval identifier source failed '{1}'", token.first));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -707,8 +709,7 @@ bool Eval::parsePrimitive (
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
bool found = false;
|
bool found = false;
|
||||||
std::vector <bool (*)(const std::string&, Variant&)>::const_iterator source;
|
for (auto source = _sources.begin (); source != _sources.end (); ++source)
|
||||||
for (source = _sources.begin (); source != _sources.end (); ++source)
|
|
||||||
{
|
{
|
||||||
Variant v;
|
Variant v;
|
||||||
if ((*source) (infix[i].first, v))
|
if ((*source) (infix[i].first, v))
|
||||||
@@ -784,16 +785,15 @@ void Eval::infixToPostfix (
|
|||||||
unsigned int precedence;
|
unsigned int precedence;
|
||||||
char associativity;
|
char associativity;
|
||||||
|
|
||||||
std::vector <std::pair <std::string, Lexer::Type>>::iterator token;
|
for (auto& token : infix)
|
||||||
for (token = infix.begin (); token != infix.end (); ++token)
|
|
||||||
{
|
{
|
||||||
if (token->second == Lexer::Type::op &&
|
if (token.second == Lexer::Type::op &&
|
||||||
token->first == "(")
|
token.first == "(")
|
||||||
{
|
{
|
||||||
op_stack.push_back (*token);
|
op_stack.push_back (token);
|
||||||
}
|
}
|
||||||
else if (token->second == Lexer::Type::op &&
|
else if (token.second == Lexer::Type::op &&
|
||||||
token->first == ")")
|
token.first == ")")
|
||||||
{
|
{
|
||||||
while (op_stack.size () &&
|
while (op_stack.size () &&
|
||||||
op_stack.back ().first != "(")
|
op_stack.back ().first != "(")
|
||||||
@@ -807,8 +807,8 @@ void Eval::infixToPostfix (
|
|||||||
else
|
else
|
||||||
throw std::string ("Mismatched parentheses in expression");
|
throw std::string ("Mismatched parentheses in expression");
|
||||||
}
|
}
|
||||||
else if (token->second == Lexer::Type::op &&
|
else if (token.second == Lexer::Type::op &&
|
||||||
identifyOperator (token->first, type, precedence, associativity))
|
identifyOperator (token.first, type, precedence, associativity))
|
||||||
{
|
{
|
||||||
char type2;
|
char type2;
|
||||||
unsigned int precedence2;
|
unsigned int precedence2;
|
||||||
@@ -822,11 +822,11 @@ void Eval::infixToPostfix (
|
|||||||
op_stack.pop_back ();
|
op_stack.pop_back ();
|
||||||
}
|
}
|
||||||
|
|
||||||
op_stack.push_back (*token);
|
op_stack.push_back (token);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
postfix.push_back (*token);
|
postfix.push_back (token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -880,8 +880,7 @@ std::string Eval::dump (
|
|||||||
color_map[Lexer::Type::duration] = Color ("rgb531 on gray6");
|
color_map[Lexer::Type::duration] = Color ("rgb531 on gray6");
|
||||||
|
|
||||||
std::string output;
|
std::string output;
|
||||||
std::vector <std::pair <std::string, Lexer::Type>>::const_iterator i;
|
for (auto i = tokens.begin (); i != tokens.end (); ++i)
|
||||||
for (i = tokens.begin (); i != tokens.end (); ++i)
|
|
||||||
{
|
{
|
||||||
if (i != tokens.begin ())
|
if (i != tokens.begin ())
|
||||||
output += ' ';
|
output += ' ';
|
||||||
|
|||||||
@@ -49,8 +49,8 @@ public:
|
|||||||
void ambiguity (bool);
|
void ambiguity (bool);
|
||||||
void debug (bool);
|
void debug (bool);
|
||||||
|
|
||||||
static void getOperators (std::vector <std::string>&);
|
static std::vector <std::string> getOperators ();
|
||||||
static void getBinaryOperators (std::vector <std::string>&);
|
static std::vector <std::string> getBinaryOperators ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void evaluatePostfixStack (const std::vector <std::pair <std::string, Lexer::Type>>&, Variant&) const;
|
void evaluatePostfixStack (const std::vector <std::pair <std::string, Lexer::Type>>&, Variant&) const;
|
||||||
|
|||||||
20
src/File.cpp
20
src/File.cpp
@@ -244,9 +244,8 @@ void File::write (const std::vector <std::string>& lines)
|
|||||||
|
|
||||||
if (_fh)
|
if (_fh)
|
||||||
{
|
{
|
||||||
std::vector <std::string>::const_iterator it;
|
for (auto& line : lines)
|
||||||
for (it = lines.begin (); it != lines.end (); ++it)
|
fputs (line.c_str (), _fh);
|
||||||
fputs (it->c_str (), _fh);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -274,9 +273,8 @@ void File::append (const std::vector <std::string>& lines)
|
|||||||
if (_fh)
|
if (_fh)
|
||||||
{
|
{
|
||||||
fseek (_fh, 0, SEEK_END);
|
fseek (_fh, 0, SEEK_END);
|
||||||
std::vector <std::string>::const_iterator it;
|
for (auto& line : lines)
|
||||||
for (it = lines.begin (); it != lines.end (); ++it)
|
fputs ((line + "\n").c_str (), _fh);
|
||||||
fputs (((*it) + "\n").c_str (), _fh);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -458,10 +456,9 @@ bool File::write (
|
|||||||
std::ios_base::out | std::ios_base::trunc);
|
std::ios_base::out | std::ios_base::trunc);
|
||||||
if (out.good ())
|
if (out.good ())
|
||||||
{
|
{
|
||||||
std::vector <std::string>::const_iterator it;
|
for (auto& line : lines)
|
||||||
for (it = lines.begin (); it != lines.end (); ++it)
|
|
||||||
{
|
{
|
||||||
out << *it;
|
out << line;
|
||||||
|
|
||||||
if (addNewlines)
|
if (addNewlines)
|
||||||
out << "\n";
|
out << "\n";
|
||||||
@@ -499,10 +496,9 @@ bool File::append (
|
|||||||
std::ios_base::out | std::ios_base::app);
|
std::ios_base::out | std::ios_base::app);
|
||||||
if (out.good ())
|
if (out.good ())
|
||||||
{
|
{
|
||||||
std::vector <std::string>::const_iterator it;
|
for (auto& line : lines)
|
||||||
for (it = lines.begin (); it != lines.end (); ++it)
|
|
||||||
{
|
{
|
||||||
out << *it;
|
out << line;
|
||||||
|
|
||||||
if (addNewlines)
|
if (addNewlines)
|
||||||
out << "\n";
|
out << "\n";
|
||||||
|
|||||||
@@ -89,16 +89,15 @@ void Filter::subset (const std::vector <Task>& input, std::vector <Task>& output
|
|||||||
eval.compileExpression (filterExpr);
|
eval.compileExpression (filterExpr);
|
||||||
eval.debug (false);
|
eval.debug (false);
|
||||||
|
|
||||||
std::vector <Task>::const_iterator task;
|
for (auto& task : input)
|
||||||
for (task = input.begin (); task != input.end (); ++task)
|
|
||||||
{
|
{
|
||||||
// Set up context for any DOM references.
|
// Set up context for any DOM references.
|
||||||
contextTask = *task;
|
contextTask = task;
|
||||||
|
|
||||||
Variant var;
|
Variant var;
|
||||||
eval.evaluateCompiledExpression (var);
|
eval.evaluateCompiledExpression (var);
|
||||||
if (var.get_bool ())
|
if (var.get_bool ())
|
||||||
output.push_back (*task);
|
output.push_back (task);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -123,7 +122,7 @@ void Filter::subset (std::vector <Task>& output, bool applyContext /* = true */)
|
|||||||
if (filterExpr.length ())
|
if (filterExpr.length ())
|
||||||
{
|
{
|
||||||
context.timer_filter.stop ();
|
context.timer_filter.stop ();
|
||||||
const std::vector <Task>& pending = context.tdb2.pending.get_tasks ();
|
auto pending = context.tdb2.pending.get_tasks ();
|
||||||
context.timer_filter.start ();
|
context.timer_filter.start ();
|
||||||
_startCount = (int) pending.size ();
|
_startCount = (int) pending.size ();
|
||||||
|
|
||||||
@@ -139,58 +138,53 @@ void Filter::subset (std::vector <Task>& output, bool applyContext /* = true */)
|
|||||||
eval.debug (false);
|
eval.debug (false);
|
||||||
|
|
||||||
output.clear ();
|
output.clear ();
|
||||||
std::vector <Task>::const_iterator task;
|
for (auto& task : pending)
|
||||||
|
|
||||||
for (task = pending.begin (); task != pending.end (); ++task)
|
|
||||||
{
|
{
|
||||||
// Set up context for any DOM references.
|
// Set up context for any DOM references.
|
||||||
contextTask = *task;
|
contextTask = task;
|
||||||
|
|
||||||
Variant var;
|
Variant var;
|
||||||
eval.debug (context.config.getInteger ("debug.parser") >= 2 ? true : false);
|
eval.debug (context.config.getInteger ("debug.parser") >= 2 ? true : false);
|
||||||
eval.evaluateCompiledExpression (var);
|
eval.evaluateCompiledExpression (var);
|
||||||
eval.debug (false);
|
eval.debug (false);
|
||||||
if (var.get_bool ())
|
if (var.get_bool ())
|
||||||
output.push_back (*task);
|
output.push_back (task);
|
||||||
}
|
}
|
||||||
|
|
||||||
shortcut = pendingOnly ();
|
shortcut = pendingOnly ();
|
||||||
if (! shortcut)
|
if (! shortcut)
|
||||||
{
|
{
|
||||||
context.timer_filter.stop ();
|
context.timer_filter.stop ();
|
||||||
const std::vector <Task>& completed = context.tdb2.completed.get_tasks ();
|
auto completed = context.tdb2.completed.get_tasks ();
|
||||||
context.timer_filter.start ();
|
context.timer_filter.start ();
|
||||||
_startCount += (int) completed.size ();
|
_startCount += (int) completed.size ();
|
||||||
|
|
||||||
for (task = completed.begin (); task != completed.end (); ++task)
|
for (auto& task : completed)
|
||||||
{
|
{
|
||||||
// Set up context for any DOM references.
|
// Set up context for any DOM references.
|
||||||
contextTask = *task;
|
contextTask = task;
|
||||||
|
|
||||||
Variant var;
|
Variant var;
|
||||||
eval.debug (context.config.getInteger ("debug.parser") >= 2 ? true : false);
|
eval.debug (context.config.getInteger ("debug.parser") >= 2 ? true : false);
|
||||||
eval.evaluateCompiledExpression (var);
|
eval.evaluateCompiledExpression (var);
|
||||||
eval.debug (false);
|
eval.debug (false);
|
||||||
if (var.get_bool ())
|
if (var.get_bool ())
|
||||||
output.push_back (*task);
|
output.push_back (task);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
safety ();
|
safety ();
|
||||||
|
|
||||||
context.timer_filter.stop ();
|
context.timer_filter.stop ();
|
||||||
const std::vector <Task>& pending = context.tdb2.pending.get_tasks ();
|
|
||||||
const std::vector <Task>& completed = context.tdb2.completed.get_tasks ();
|
for (auto& task : context.tdb2.pending.get_tasks ())
|
||||||
|
output.push_back (task);
|
||||||
|
|
||||||
|
for (auto& task : context.tdb2.completed.get_tasks ())
|
||||||
|
output.push_back (task);
|
||||||
|
|
||||||
context.timer_filter.start ();
|
context.timer_filter.start ();
|
||||||
|
|
||||||
std::vector <Task>::const_iterator task;
|
|
||||||
for (task = pending.begin (); task != pending.end (); ++task)
|
|
||||||
output.push_back (*task);
|
|
||||||
|
|
||||||
for (task = completed.begin (); task != completed.end (); ++task)
|
|
||||||
output.push_back (*task);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_endCount = (int) output.size ();
|
_endCount = (int) output.size ();
|
||||||
@@ -218,19 +212,18 @@ bool Filter::pendingOnly ()
|
|||||||
int countXor = 0;
|
int countXor = 0;
|
||||||
int countNot = 0;
|
int countNot = 0;
|
||||||
|
|
||||||
std::vector <A>::iterator a;
|
for (auto& a : context.cli._args)
|
||||||
for (a = context.cli._args.begin (); a != context.cli._args.end (); ++a)
|
|
||||||
{
|
{
|
||||||
if (a->hasTag ("FILTER"))
|
if (a.hasTag ("FILTER"))
|
||||||
{
|
{
|
||||||
if (a->hasTag ("ID")) ++countId;
|
if (a.hasTag ("ID")) ++countId;
|
||||||
if (a->hasTag ("OP") && a->attribute ("raw") == "or") ++countOr;
|
if (a.hasTag ("OP") && a.attribute ("raw") == "or") ++countOr;
|
||||||
if (a->hasTag ("OP") && a->attribute ("raw") == "xor") ++countXor;
|
if (a.hasTag ("OP") && a.attribute ("raw") == "xor") ++countXor;
|
||||||
if (a->hasTag ("OP") && a->attribute ("raw") == "not") ++countNot;
|
if (a.hasTag ("OP") && a.attribute ("raw") == "not") ++countNot;
|
||||||
if (a->hasTag ("ATTRIBUTE") && a->attribute ("name") == "status") ++countStatus;
|
if (a.hasTag ("ATTRIBUTE") && a.attribute ("name") == "status") ++countStatus;
|
||||||
if ( a->attribute ("raw") == "pending") ++countPending;
|
if ( a.attribute ("raw") == "pending") ++countPending;
|
||||||
if ( a->attribute ("raw") == "waiting") ++countWaiting;
|
if ( a.attribute ("raw") == "waiting") ++countWaiting;
|
||||||
if ( a->attribute ("raw") == "recurring") ++countRecurring;
|
if ( a.attribute ("raw") == "recurring") ++countRecurring;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -258,12 +251,11 @@ bool Filter::pendingOnly ()
|
|||||||
// all tasks to be modified. This is usually not intended.
|
// all tasks to be modified. This is usually not intended.
|
||||||
void Filter::safety ()
|
void Filter::safety ()
|
||||||
{
|
{
|
||||||
std::vector <A>::iterator a;
|
for (auto& a : context.cli._args)
|
||||||
for (a = context.cli._args.begin (); a != context.cli._args.end (); ++a)
|
|
||||||
{
|
{
|
||||||
if (a->hasTag ("CMD"))
|
if (a.hasTag ("CMD"))
|
||||||
{
|
{
|
||||||
if (a->hasTag ("WRITECMD"))
|
if (a.hasTag ("WRITECMD"))
|
||||||
{
|
{
|
||||||
if (context.cli.getFilter () == "")
|
if (context.cli.getFilter () == "")
|
||||||
{
|
{
|
||||||
|
|||||||
142
src/Hooks.cpp
142
src/Hooks.cpp
@@ -73,18 +73,17 @@ void Hooks::initialize ()
|
|||||||
|
|
||||||
if (_debug >= 1)
|
if (_debug >= 1)
|
||||||
{
|
{
|
||||||
std::vector <std::string>::iterator i;
|
for (auto& i : _scripts)
|
||||||
for (i = _scripts.begin (); i != _scripts.end (); ++i)
|
|
||||||
{
|
{
|
||||||
Path p (*i);
|
Path p (i);
|
||||||
std::string name = p.name ();
|
std::string name = p.name ();
|
||||||
if (name.substr (0, 6) == "on-add" ||
|
if (name.substr (0, 6) == "on-add" ||
|
||||||
name.substr (0, 9) == "on-modify" ||
|
name.substr (0, 9) == "on-modify" ||
|
||||||
name.substr (0, 9) == "on-launch" ||
|
name.substr (0, 9) == "on-launch" ||
|
||||||
name.substr (0, 7) == "on-exit")
|
name.substr (0, 7) == "on-exit")
|
||||||
context.debug ("Found hook script " + *i);
|
context.debug ("Found hook script " + i);
|
||||||
else
|
else
|
||||||
context.debug ("Found misnamed hook script " + *i);
|
context.debug ("Found misnamed hook script " + i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -124,12 +123,11 @@ void Hooks::onLaunch ()
|
|||||||
std::vector <std::string> matchingScripts = scripts ("on-launch");
|
std::vector <std::string> matchingScripts = scripts ("on-launch");
|
||||||
if (matchingScripts.size ())
|
if (matchingScripts.size ())
|
||||||
{
|
{
|
||||||
std::vector <std::string>::iterator script;
|
for (auto& script : matchingScripts)
|
||||||
for (script = matchingScripts.begin (); script != matchingScripts.end (); ++script)
|
|
||||||
{
|
{
|
||||||
std::vector <std::string> input;
|
std::vector <std::string> input;
|
||||||
std::vector <std::string> output;
|
std::vector <std::string> output;
|
||||||
int status = callHookScript (*script, input, output);
|
int status = callHookScript (script, input, output);
|
||||||
|
|
||||||
std::vector <std::string> outputJSON;
|
std::vector <std::string> outputJSON;
|
||||||
std::vector <std::string> outputFeedback;
|
std::vector <std::string> outputFeedback;
|
||||||
@@ -139,17 +137,14 @@ void Hooks::onLaunch ()
|
|||||||
|
|
||||||
if (status == 0)
|
if (status == 0)
|
||||||
{
|
{
|
||||||
std::vector <std::string>::iterator message;
|
for (auto& message : outputFeedback)
|
||||||
for (message = outputFeedback.begin (); message != outputFeedback.end (); ++message)
|
context.footnote (message);
|
||||||
context.footnote (*message);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
assertFeedback (outputFeedback);
|
assertFeedback (outputFeedback);
|
||||||
|
for (auto& message : outputFeedback)
|
||||||
std::vector <std::string>::iterator message;
|
context.error (message);
|
||||||
for (message = outputFeedback.begin (); message != outputFeedback.end (); ++message)
|
|
||||||
context.error (*message);
|
|
||||||
|
|
||||||
throw 0; // This is how hooks silently terminate processing.
|
throw 0; // This is how hooks silently terminate processing.
|
||||||
}
|
}
|
||||||
@@ -187,16 +182,14 @@ void Hooks::onExit ()
|
|||||||
|
|
||||||
// Convert to a vector of strings.
|
// Convert to a vector of strings.
|
||||||
std::vector <std::string> input;
|
std::vector <std::string> input;
|
||||||
std::vector <Task>::const_iterator t;
|
for (auto& t : tasks)
|
||||||
for (t = tasks.begin (); t != tasks.end (); ++t)
|
input.push_back (t.composeJSON ());
|
||||||
input.push_back (t->composeJSON ());
|
|
||||||
|
|
||||||
// Call the hook scripts, with the invariant input.
|
// Call the hook scripts, with the invariant input.
|
||||||
std::vector <std::string>::iterator script;
|
for (auto& script : matchingScripts)
|
||||||
for (script = matchingScripts.begin (); script != matchingScripts.end (); ++script)
|
|
||||||
{
|
{
|
||||||
std::vector <std::string> output;
|
std::vector <std::string> output;
|
||||||
int status = callHookScript (*script, input, output);
|
int status = callHookScript (script, input, output);
|
||||||
|
|
||||||
std::vector <std::string> outputJSON;
|
std::vector <std::string> outputJSON;
|
||||||
std::vector <std::string> outputFeedback;
|
std::vector <std::string> outputFeedback;
|
||||||
@@ -206,17 +199,14 @@ void Hooks::onExit ()
|
|||||||
|
|
||||||
if (status == 0)
|
if (status == 0)
|
||||||
{
|
{
|
||||||
std::vector <std::string>::iterator message;
|
for (auto& message : outputFeedback)
|
||||||
for (message = outputFeedback.begin (); message != outputFeedback.end (); ++message)
|
context.footnote (message);
|
||||||
context.footnote (*message);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
assertFeedback (outputFeedback);
|
assertFeedback (outputFeedback);
|
||||||
|
for (auto& message : outputFeedback)
|
||||||
std::vector <std::string>::iterator message;
|
context.error (message);
|
||||||
for (message = outputFeedback.begin (); message != outputFeedback.end (); ++message)
|
|
||||||
context.error (*message);
|
|
||||||
|
|
||||||
throw 0; // This is how hooks silently terminate processing.
|
throw 0; // This is how hooks silently terminate processing.
|
||||||
}
|
}
|
||||||
@@ -253,11 +243,10 @@ void Hooks::onAdd (Task& task)
|
|||||||
input.push_back (task.composeJSON ());
|
input.push_back (task.composeJSON ());
|
||||||
|
|
||||||
// Call the hook scripts.
|
// Call the hook scripts.
|
||||||
std::vector <std::string>::iterator script;
|
for (auto& script : matchingScripts)
|
||||||
for (script = matchingScripts.begin (); script != matchingScripts.end (); ++script)
|
|
||||||
{
|
{
|
||||||
std::vector <std::string> output;
|
std::vector <std::string> output;
|
||||||
int status = callHookScript (*script, input, output);
|
int status = callHookScript (script, input, output);
|
||||||
|
|
||||||
std::vector <std::string> outputJSON;
|
std::vector <std::string> outputJSON;
|
||||||
std::vector <std::string> outputFeedback;
|
std::vector <std::string> outputFeedback;
|
||||||
@@ -272,17 +261,14 @@ void Hooks::onAdd (Task& task)
|
|||||||
// Propagate forward to the next script.
|
// Propagate forward to the next script.
|
||||||
input[0] = outputJSON[0];
|
input[0] = outputJSON[0];
|
||||||
|
|
||||||
std::vector <std::string>::iterator message;
|
for (auto& message : outputFeedback)
|
||||||
for (message = outputFeedback.begin (); message != outputFeedback.end (); ++message)
|
context.footnote (message);
|
||||||
context.footnote (*message);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
assertFeedback (outputFeedback);
|
assertFeedback (outputFeedback);
|
||||||
|
for (auto& message : outputFeedback)
|
||||||
std::vector <std::string>::iterator message;
|
context.error (message);
|
||||||
for (message = outputFeedback.begin (); message != outputFeedback.end (); ++message)
|
|
||||||
context.error (*message);
|
|
||||||
|
|
||||||
throw 0; // This is how hooks silently terminate processing.
|
throw 0; // This is how hooks silently terminate processing.
|
||||||
}
|
}
|
||||||
@@ -324,11 +310,10 @@ void Hooks::onModify (const Task& before, Task& after)
|
|||||||
input.push_back (after.composeJSON ()); // [line 1] modified
|
input.push_back (after.composeJSON ()); // [line 1] modified
|
||||||
|
|
||||||
// Call the hook scripts.
|
// Call the hook scripts.
|
||||||
std::vector <std::string>::iterator script;
|
for (auto& script : matchingScripts)
|
||||||
for (script = matchingScripts.begin (); script != matchingScripts.end (); ++script)
|
|
||||||
{
|
{
|
||||||
std::vector <std::string> output;
|
std::vector <std::string> output;
|
||||||
int status = callHookScript (*script, input, output);
|
int status = callHookScript (script, input, output);
|
||||||
|
|
||||||
std::vector <std::string> outputJSON;
|
std::vector <std::string> outputJSON;
|
||||||
std::vector <std::string> outputFeedback;
|
std::vector <std::string> outputFeedback;
|
||||||
@@ -343,17 +328,14 @@ void Hooks::onModify (const Task& before, Task& after)
|
|||||||
// Propagate accepted changes forward to the next script.
|
// Propagate accepted changes forward to the next script.
|
||||||
input[1] = outputJSON[0];
|
input[1] = outputJSON[0];
|
||||||
|
|
||||||
std::vector <std::string>::iterator message;
|
for (auto& message : outputFeedback)
|
||||||
for (message = outputFeedback.begin (); message != outputFeedback.end (); ++message)
|
context.footnote (message);
|
||||||
context.footnote (*message);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
assertFeedback (outputFeedback);
|
assertFeedback (outputFeedback);
|
||||||
|
for (auto& message : outputFeedback)
|
||||||
std::vector <std::string>::iterator message;
|
context.error (message);
|
||||||
for (message = outputFeedback.begin (); message != outputFeedback.end (); ++message)
|
|
||||||
context.error (*message);
|
|
||||||
|
|
||||||
throw 0; // This is how hooks silently terminate processing.
|
throw 0; // This is how hooks silently terminate processing.
|
||||||
}
|
}
|
||||||
@@ -375,14 +357,13 @@ std::vector <std::string> Hooks::list ()
|
|||||||
std::vector <std::string> Hooks::scripts (const std::string& event)
|
std::vector <std::string> Hooks::scripts (const std::string& event)
|
||||||
{
|
{
|
||||||
std::vector <std::string> matching;
|
std::vector <std::string> matching;
|
||||||
std::vector <std::string>::iterator i;
|
for (auto& i : _scripts)
|
||||||
for (i = _scripts.begin (); i != _scripts.end (); ++i)
|
|
||||||
{
|
{
|
||||||
if (i->find ("/" + event) != std::string::npos)
|
if (i.find ("/" + event) != std::string::npos)
|
||||||
{
|
{
|
||||||
File script (*i);
|
File script (i);
|
||||||
if (script.executable ())
|
if (script.executable ())
|
||||||
matching.push_back (*i);
|
matching.push_back (i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -395,13 +376,12 @@ void Hooks::separateOutput (
|
|||||||
std::vector <std::string>& json,
|
std::vector <std::string>& json,
|
||||||
std::vector <std::string>& feedback) const
|
std::vector <std::string>& feedback) const
|
||||||
{
|
{
|
||||||
std::vector <std::string>::const_iterator i;
|
for (auto& i : output)
|
||||||
for (i = output.begin (); i != output.end (); ++i)
|
|
||||||
{
|
{
|
||||||
if (isJSON (*i))
|
if (isJSON (i))
|
||||||
json.push_back (*i);
|
json.push_back (i);
|
||||||
else
|
else
|
||||||
feedback.push_back (*i);
|
feedback.push_back (i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -416,12 +396,11 @@ bool Hooks::isJSON (const std::string& input) const
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void Hooks::assertValidJSON (const std::vector <std::string>& input) const
|
void Hooks::assertValidJSON (const std::vector <std::string>& input) const
|
||||||
{
|
{
|
||||||
std::vector <std::string>::const_iterator i;
|
for (auto& i : input)
|
||||||
for (i = input.begin (); i != input.end (); i++)
|
|
||||||
{
|
{
|
||||||
if (i->length () < 3 ||
|
if (i.length () < 3 ||
|
||||||
(*i)[0] != '{' ||
|
i[0] != '{' ||
|
||||||
(*i)[i->length () - 1] != '}')
|
i[i.length () - 1] != '}')
|
||||||
{
|
{
|
||||||
context.error (STRING_HOOK_ERROR_OBJECT);
|
context.error (STRING_HOOK_ERROR_OBJECT);
|
||||||
throw 0;
|
throw 0;
|
||||||
@@ -429,7 +408,7 @@ void Hooks::assertValidJSON (const std::vector <std::string>& input) const
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
json::value* root = json::parse (*i);
|
json::value* root = json::parse (i);
|
||||||
if (root->type () != json::j_object)
|
if (root->type () != json::j_object)
|
||||||
{
|
{
|
||||||
context.error (STRING_HOOK_ERROR_OBJECT);
|
context.error (STRING_HOOK_ERROR_OBJECT);
|
||||||
@@ -451,7 +430,7 @@ void Hooks::assertValidJSON (const std::vector <std::string>& input) const
|
|||||||
|
|
||||||
catch (const std::string& e)
|
catch (const std::string& e)
|
||||||
{
|
{
|
||||||
context.error (format (STRING_HOOK_ERROR_SYNTAX, *i));
|
context.error (format (STRING_HOOK_ERROR_SYNTAX, i));
|
||||||
if (_debug)
|
if (_debug)
|
||||||
context.error (STRING_HOOK_ERROR_JSON + e);
|
context.error (STRING_HOOK_ERROR_JSON + e);
|
||||||
throw 0;
|
throw 0;
|
||||||
@@ -459,7 +438,7 @@ void Hooks::assertValidJSON (const std::vector <std::string>& input) const
|
|||||||
|
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
context.error (STRING_HOOK_ERROR_NOPARSE + *i);
|
context.error (STRING_HOOK_ERROR_NOPARSE + i);
|
||||||
throw 0;
|
throw 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -480,13 +459,12 @@ void Hooks::assertSameTask (const std::vector <std::string>& input, const Task&
|
|||||||
{
|
{
|
||||||
std::string uuid = task.get ("uuid");
|
std::string uuid = task.get ("uuid");
|
||||||
|
|
||||||
std::vector <std::string>::const_iterator i;
|
for (auto& i : input)
|
||||||
for (i = input.begin (); i != input.end (); i++)
|
|
||||||
{
|
{
|
||||||
json::object* root_obj = (json::object*)json::parse (*i);
|
json::object* root_obj = (json::object*)json::parse (i);
|
||||||
|
|
||||||
// If there is no UUID at all.
|
// If there is no UUID at all.
|
||||||
json_object_iter u = root_obj->_data.find ("uuid");
|
auto u = root_obj->_data.find ("uuid");
|
||||||
if (u == root_obj->_data.end () ||
|
if (u == root_obj->_data.end () ||
|
||||||
u->second->type () != json::j_string)
|
u->second->type () != json::j_string)
|
||||||
{
|
{
|
||||||
@@ -508,9 +486,8 @@ void Hooks::assertSameTask (const std::vector <std::string>& input, const Task&
|
|||||||
void Hooks::assertFeedback (const std::vector <std::string>& input) const
|
void Hooks::assertFeedback (const std::vector <std::string>& input) const
|
||||||
{
|
{
|
||||||
bool foundSomething = false;
|
bool foundSomething = false;
|
||||||
std::vector <std::string>::const_iterator i;
|
for (auto& i : input)
|
||||||
for (i = input.begin (); i != input.end (); ++i)
|
if (nontrivial (i))
|
||||||
if (nontrivial (*i))
|
|
||||||
foundSomething = true;
|
foundSomething = true;
|
||||||
|
|
||||||
if (! foundSomething)
|
if (! foundSomething)
|
||||||
@@ -559,22 +536,20 @@ int Hooks::callHookScript (
|
|||||||
if (_debug >= 2)
|
if (_debug >= 2)
|
||||||
{
|
{
|
||||||
context.debug ("Hook: input");
|
context.debug ("Hook: input");
|
||||||
std::vector <std::string>::const_iterator i;
|
for (auto& i : input)
|
||||||
for (i = input.begin (); i != input.end (); ++i)
|
context.debug (" " + i);
|
||||||
context.debug (" " + *i);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string inputStr;
|
std::string inputStr;
|
||||||
std::vector <std::string>::const_iterator i;
|
for (auto& i : input)
|
||||||
for (i = input.begin (); i != input.end (); ++i)
|
inputStr += i + "\n";
|
||||||
inputStr += *i + "\n";
|
|
||||||
|
|
||||||
std::vector <std::string> args;
|
std::vector <std::string> args;
|
||||||
buildHookScriptArgs (args);
|
buildHookScriptArgs (args);
|
||||||
if (_debug >= 2)
|
if (_debug >= 2)
|
||||||
{
|
{
|
||||||
context.debug ("Hooks: args");
|
context.debug ("Hooks: args");
|
||||||
for (auto arg: args)
|
for (auto& arg: args)
|
||||||
context.debug (" " + arg);
|
context.debug (" " + arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -596,10 +571,9 @@ int Hooks::callHookScript (
|
|||||||
if (_debug >= 2)
|
if (_debug >= 2)
|
||||||
{
|
{
|
||||||
context.debug ("Hook: output");
|
context.debug ("Hook: output");
|
||||||
std::vector <std::string>::iterator i;
|
for (auto& i : output)
|
||||||
for (i = output.begin (); i != output.end (); ++i)
|
if (i != "")
|
||||||
if (*i != "")
|
context.debug (" " + i);
|
||||||
context.debug (" " + *i);
|
|
||||||
|
|
||||||
context.debug (format ("Hook: Completed with status {1}", status));
|
context.debug (format ("Hook: Completed with status {1}", status));
|
||||||
context.debug (" "); // Blank line
|
context.debug (" "); // Blank line
|
||||||
|
|||||||
24
src/JSON.cpp
24
src/JSON.cpp
@@ -162,9 +162,8 @@ std::string json::literal::dump ()
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
json::array::~array ()
|
json::array::~array ()
|
||||||
{
|
{
|
||||||
std::vector <json::value*>::iterator i;
|
for (auto& i : _data)
|
||||||
for (i = _data.begin (); i != _data.end (); ++i)
|
delete i;
|
||||||
delete *i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -227,10 +226,7 @@ std::string json::array::dump ()
|
|||||||
std::string output;
|
std::string output;
|
||||||
output += "[";
|
output += "[";
|
||||||
|
|
||||||
std::vector <json::value*>::iterator i;
|
for (auto i = _data.begin (); i != _data.end (); ++i)
|
||||||
for (i = _data.begin ();
|
|
||||||
i != _data.end ();
|
|
||||||
++i)
|
|
||||||
{
|
{
|
||||||
if (i != _data.begin ())
|
if (i != _data.begin ())
|
||||||
output += ",";
|
output += ",";
|
||||||
@@ -245,9 +241,8 @@ std::string json::array::dump ()
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
json::object::~object ()
|
json::object::~object ()
|
||||||
{
|
{
|
||||||
std::map <std::string, json::value*>::iterator i;
|
for (auto& i : _data)
|
||||||
for (i = _data.begin (); i != _data.end (); ++i)
|
delete i.second;
|
||||||
delete i->second;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -341,8 +336,7 @@ std::string json::object::dump ()
|
|||||||
std::string output;
|
std::string output;
|
||||||
output += "{";
|
output += "{";
|
||||||
|
|
||||||
std::map <std::string, json::value*>::iterator i;
|
for (auto i = _data.begin (); i != _data.end (); ++i)
|
||||||
for (i = _data.begin (); i != _data.end (); ++i)
|
|
||||||
{
|
{
|
||||||
if (i != _data.begin ())
|
if (i != _data.begin ())
|
||||||
output += ",";
|
output += ",";
|
||||||
@@ -384,9 +378,9 @@ std::string json::encode (const std::string& input)
|
|||||||
{
|
{
|
||||||
std::string output;
|
std::string output;
|
||||||
|
|
||||||
for (std::string::size_type i = 0; i < input.length (); ++i)
|
for (auto& i : input)
|
||||||
{
|
{
|
||||||
switch (input[i])
|
switch (i)
|
||||||
{
|
{
|
||||||
// Simple translations.
|
// Simple translations.
|
||||||
case '"': output += "\\\""; break;
|
case '"': output += "\\\""; break;
|
||||||
@@ -399,7 +393,7 @@ std::string json::encode (const std::string& input)
|
|||||||
case '\t': output += "\\t"; break;
|
case '\t': output += "\\t"; break;
|
||||||
|
|
||||||
// Default NOP.
|
// Default NOP.
|
||||||
default: output += input[i]; break;
|
default: output += i; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -131,8 +131,5 @@ namespace json
|
|||||||
std::string decode (const std::string&);
|
std::string decode (const std::string&);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef std::vector <json::value*>::iterator json_array_iter;
|
|
||||||
typedef std::map <std::string, json::value*>::iterator json_object_iter;
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|||||||
24
src/Msg.cpp
24
src/Msg.cpp
@@ -102,8 +102,7 @@ void Msg::setPayload (const std::string& payload)
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
std::string Msg::get (const std::string& name) const
|
std::string Msg::get (const std::string& name) const
|
||||||
{
|
{
|
||||||
std::map <std::string, std::string>::const_iterator i;
|
auto i = _header.find (name);
|
||||||
i = _header.find (name);
|
|
||||||
if (i != _header.end ())
|
if (i != _header.end ())
|
||||||
return i->second;
|
return i->second;
|
||||||
|
|
||||||
@@ -119,9 +118,8 @@ std::string Msg::getPayload () const
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void Msg::all (std::vector <std::string>& names) const
|
void Msg::all (std::vector <std::string>& names) const
|
||||||
{
|
{
|
||||||
std::map <std::string, std::string>::const_iterator i;
|
for (auto& i : _header)
|
||||||
for (i = _header.begin (); i != _header.end (); ++i)
|
names.push_back (i.first);
|
||||||
names.push_back (i->first);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -129,9 +127,8 @@ std::string Msg::serialize () const
|
|||||||
{
|
{
|
||||||
std::string output;
|
std::string output;
|
||||||
|
|
||||||
std::map <std::string, std::string>::const_iterator i;
|
for (auto& i : _header)
|
||||||
for (i = _header.begin (); i != _header.end (); ++i)
|
output += i.first + ": " + i.second + "\n";
|
||||||
output += i->first + ": " + i->second + "\n";
|
|
||||||
|
|
||||||
output += "\n" + _payload + "\n";
|
output += "\n" + _payload + "\n";
|
||||||
|
|
||||||
@@ -144,21 +141,20 @@ bool Msg::parse (const std::string& input)
|
|||||||
_header.clear ();
|
_header.clear ();
|
||||||
_payload = "";
|
_payload = "";
|
||||||
|
|
||||||
std::string::size_type separator = input.find ("\n\n");
|
auto separator = input.find ("\n\n");
|
||||||
if (separator == std::string::npos)
|
if (separator == std::string::npos)
|
||||||
throw std::string ("ERROR: Malformed message");
|
throw std::string ("ERROR: Malformed message");
|
||||||
|
|
||||||
// Parse header.
|
// Parse header.
|
||||||
std::vector <std::string> lines;
|
std::vector <std::string> lines;
|
||||||
split (lines, input.substr (0, separator), '\n');
|
split (lines, input.substr (0, separator), '\n');
|
||||||
std::vector <std::string>::iterator i;
|
for (auto& i : lines)
|
||||||
for (i = lines.begin (); i != lines.end (); ++i)
|
|
||||||
{
|
{
|
||||||
std::string::size_type delimiter = i->find (':');
|
std::string::size_type delimiter = i.find (':');
|
||||||
if (delimiter == std::string::npos)
|
if (delimiter == std::string::npos)
|
||||||
throw std::string ("ERROR: Malformed message header '") + *i + "'";
|
throw std::string ("ERROR: Malformed message header '") + i + "'";
|
||||||
|
|
||||||
_header[trim (i->substr (0, delimiter))] = trim (i->substr (delimiter + 1));
|
_header[trim (i.substr (0, delimiter))] = trim (i.substr (delimiter + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse payload.
|
// Parse payload.
|
||||||
|
|||||||
@@ -982,12 +982,11 @@ bool Nibbler::getOneOf (
|
|||||||
const std::vector <std::string>& options,
|
const std::vector <std::string>& options,
|
||||||
std::string& found)
|
std::string& found)
|
||||||
{
|
{
|
||||||
std::vector <std::string>::const_iterator option;
|
for (auto& option : options)
|
||||||
for (option = options.begin (); option != options.end (); ++option)
|
|
||||||
{
|
{
|
||||||
if (getLiteral (*option))
|
if (getLiteral (option))
|
||||||
{
|
{
|
||||||
found = *option;
|
found = option;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
300
src/TDB2.cpp
300
src/TDB2.cpp
@@ -121,12 +121,11 @@ bool TF2::get (const std::string& uuid, Task& task)
|
|||||||
if (! _loaded_tasks)
|
if (! _loaded_tasks)
|
||||||
load_tasks ();
|
load_tasks ();
|
||||||
|
|
||||||
std::vector <Task>::iterator i;
|
for (auto& i : _tasks)
|
||||||
for (i = _tasks.begin (); i != _tasks.end (); ++i)
|
|
||||||
{
|
{
|
||||||
if (i->get ("uuid") == uuid)
|
if (i.get ("uuid") == uuid)
|
||||||
{
|
{
|
||||||
task = *i;
|
task = i;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -140,9 +139,8 @@ bool TF2::has (const std::string& uuid)
|
|||||||
if (! _loaded_tasks)
|
if (! _loaded_tasks)
|
||||||
load_tasks ();
|
load_tasks ();
|
||||||
|
|
||||||
std::vector <Task>::iterator i;
|
for (auto& i : _tasks)
|
||||||
for (i = _tasks.begin (); i != _tasks.end (); ++i)
|
if (i.get ("uuid") == uuid)
|
||||||
if (i->get ("uuid") == uuid)
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -174,12 +172,11 @@ bool TF2::modify_task (const Task& task)
|
|||||||
{
|
{
|
||||||
// Modify in-place.
|
// Modify in-place.
|
||||||
std::string uuid = task.get ("uuid");
|
std::string uuid = task.get ("uuid");
|
||||||
std::vector <Task>::iterator i;
|
for (auto& i : _tasks)
|
||||||
for (i = _tasks.begin (); i != _tasks.end (); ++i)
|
|
||||||
{
|
{
|
||||||
if (i->get ("uuid") == uuid)
|
if (i.get ("uuid") == uuid)
|
||||||
{
|
{
|
||||||
*i = task;
|
i = task;
|
||||||
_modified_tasks.push_back (task);
|
_modified_tasks.push_back (task);
|
||||||
_dirty = true;
|
_dirty = true;
|
||||||
|
|
||||||
@@ -229,24 +226,14 @@ void TF2::commit ()
|
|||||||
_file.lock ();
|
_file.lock ();
|
||||||
|
|
||||||
// Write out all the added tasks.
|
// Write out all the added tasks.
|
||||||
std::vector <Task>::iterator task;
|
for (auto& task : _added_tasks)
|
||||||
for (task = _added_tasks.begin ();
|
_file.append (task.composeF4 () + "\n");
|
||||||
task != _added_tasks.end ();
|
|
||||||
++task)
|
|
||||||
{
|
|
||||||
_file.append (task->composeF4 () + "\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
_added_tasks.clear ();
|
_added_tasks.clear ();
|
||||||
|
|
||||||
// Write out all the added lines.
|
// Write out all the added lines.
|
||||||
std::vector <std::string>::iterator line;
|
for (auto& line : _added_lines)
|
||||||
for (line = _added_lines.begin ();
|
_file.append (line);
|
||||||
line != _added_lines.end ();
|
|
||||||
++line)
|
|
||||||
{
|
|
||||||
_file.append (*line);
|
|
||||||
}
|
|
||||||
|
|
||||||
_added_lines.clear ();
|
_added_lines.clear ();
|
||||||
_file.close ();
|
_file.close ();
|
||||||
@@ -264,22 +251,12 @@ void TF2::commit ()
|
|||||||
_file.truncate ();
|
_file.truncate ();
|
||||||
|
|
||||||
// Only write out _tasks, because any deltas have already been applied.
|
// Only write out _tasks, because any deltas have already been applied.
|
||||||
std::vector <Task>::iterator task;
|
for (auto& task : _tasks)
|
||||||
for (task = _tasks.begin ();
|
_file.append (task.composeF4 () + "\n");
|
||||||
task != _tasks.end ();
|
|
||||||
++task)
|
|
||||||
{
|
|
||||||
_file.append (task->composeF4 () + "\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write out all the added lines.
|
// Write out all the added lines.
|
||||||
std::vector <std::string>::iterator line;
|
for (auto& line : _added_lines)
|
||||||
for (line = _added_lines.begin ();
|
_file.append (line);
|
||||||
line != _added_lines.end ();
|
|
||||||
++line)
|
|
||||||
{
|
|
||||||
_file.append (*line);
|
|
||||||
}
|
|
||||||
|
|
||||||
_added_lines.clear ();
|
_added_lines.clear ();
|
||||||
_file.close ();
|
_file.close ();
|
||||||
@@ -299,9 +276,8 @@ void TF2::load_tasks ()
|
|||||||
load_lines ();
|
load_lines ();
|
||||||
|
|
||||||
// Apply previously added lines.
|
// Apply previously added lines.
|
||||||
std::vector <std::string>::iterator i;
|
for (auto& line : _added_lines)
|
||||||
for (i = _added_lines.begin (); i != _added_lines.end (); ++i)
|
_lines.push_back (line);
|
||||||
_lines.push_back (*i);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int line_number = 0;
|
int line_number = 0;
|
||||||
@@ -310,11 +286,10 @@ void TF2::load_tasks ()
|
|||||||
// Reduce unnecessary allocations/copies.
|
// Reduce unnecessary allocations/copies.
|
||||||
_tasks.reserve (_lines.size ());
|
_tasks.reserve (_lines.size ());
|
||||||
|
|
||||||
std::vector <std::string>::iterator i;
|
for (auto& line : _lines)
|
||||||
for (i = _lines.begin (); i != _lines.end (); ++i)
|
|
||||||
{
|
{
|
||||||
++line_number;
|
++line_number;
|
||||||
Task task (*i);
|
Task task (line);
|
||||||
|
|
||||||
// Some tasks get an ID.
|
// Some tasks get an ID.
|
||||||
if (_has_ids)
|
if (_has_ids)
|
||||||
@@ -374,13 +349,12 @@ std::string TF2::uuid (int id)
|
|||||||
load_tasks ();
|
load_tasks ();
|
||||||
|
|
||||||
// Apply previously added tasks.
|
// Apply previously added tasks.
|
||||||
std::vector <Task>::iterator i;
|
for (auto& task : _added_tasks)
|
||||||
for (i = _added_tasks.begin (); i != _added_tasks.end (); ++i)
|
_tasks.push_back (task);
|
||||||
_tasks.push_back (*i);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map <int, std::string>::const_iterator i;
|
auto i = _I2U.find (id);
|
||||||
if ((i = _I2U.find (id)) != _I2U.end ())
|
if (i != _I2U.end ())
|
||||||
return i->second;
|
return i->second;
|
||||||
|
|
||||||
return "";
|
return "";
|
||||||
@@ -394,13 +368,12 @@ int TF2::id (const std::string& uuid)
|
|||||||
load_tasks ();
|
load_tasks ();
|
||||||
|
|
||||||
// Apply previously added tasks.
|
// Apply previously added tasks.
|
||||||
std::vector <Task>::iterator i;
|
for (auto& task : _added_tasks)
|
||||||
for (i = _added_tasks.begin (); i != _added_tasks.end (); ++i)
|
_tasks.push_back (task);
|
||||||
_tasks.push_back (*i);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map <std::string, int>::const_iterator i;
|
auto i = _U2I.find (uuid);
|
||||||
if ((i = _U2I.find (uuid)) != _U2I.end ())
|
if (i != _U2I.end ())
|
||||||
return i->second;
|
return i->second;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -448,38 +421,32 @@ void TF2::clear ()
|
|||||||
void TF2::dependency_scan ()
|
void TF2::dependency_scan ()
|
||||||
{
|
{
|
||||||
// Iterate and modify TDB2 in-place. Don't do this at home.
|
// Iterate and modify TDB2 in-place. Don't do this at home.
|
||||||
std::vector <Task>::iterator left;
|
for (auto& left : _tasks)
|
||||||
for (left = _tasks.begin ();
|
|
||||||
left != _tasks.end ();
|
|
||||||
++left)
|
|
||||||
{
|
{
|
||||||
if (left->has ("depends"))
|
if (left.has ("depends"))
|
||||||
{
|
{
|
||||||
std::vector <std::string> deps;
|
std::vector <std::string> deps;
|
||||||
left->getDependencies (deps);
|
left.getDependencies (deps);
|
||||||
|
|
||||||
std::vector <std::string>::iterator d;
|
for (auto& dep : deps)
|
||||||
for (d = deps.begin (); d != deps.end (); ++d)
|
|
||||||
{
|
{
|
||||||
std::vector <Task>::iterator right;
|
for (auto& right : _tasks)
|
||||||
for (right = _tasks.begin ();
|
|
||||||
right != _tasks.end ();
|
|
||||||
++right)
|
|
||||||
{
|
{
|
||||||
if (right->get ("uuid") == *d)
|
if (right.get ("uuid") == dep)
|
||||||
{
|
{
|
||||||
// GC hasn't run yet, check both tasks for their current status
|
// GC hasn't run yet, check both tasks for their current status
|
||||||
Task::status lstatus = left->getStatus ();
|
Task::status lstatus = left.getStatus ();
|
||||||
Task::status rstatus = right->getStatus ();
|
Task::status rstatus = right.getStatus ();
|
||||||
if (lstatus != Task::completed &&
|
if (lstatus != Task::completed &&
|
||||||
lstatus != Task::deleted &&
|
lstatus != Task::deleted &&
|
||||||
rstatus != Task::completed &&
|
rstatus != Task::completed &&
|
||||||
rstatus != Task::deleted)
|
rstatus != Task::deleted)
|
||||||
{
|
{
|
||||||
left->is_blocked = true;
|
left.is_blocked = true;
|
||||||
right->is_blocking = true;
|
right.is_blocking = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Only want to break out of the "right" loop.
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -701,18 +668,17 @@ void TDB2::commit ()
|
|||||||
void TDB2::gather_changes ()
|
void TDB2::gather_changes ()
|
||||||
{
|
{
|
||||||
_changes.clear ();
|
_changes.clear ();
|
||||||
std::vector <Task>::iterator i;
|
for (auto& task : pending._added_tasks)
|
||||||
for (i = pending._added_tasks.begin (); i != pending._added_tasks.end (); ++i)
|
_changes.push_back (task);
|
||||||
_changes.push_back (*i);
|
|
||||||
|
|
||||||
for (i = pending._modified_tasks.begin (); i != pending._modified_tasks.end (); ++i)
|
for (auto& task : pending._modified_tasks)
|
||||||
_changes.push_back (*i);
|
_changes.push_back (task);
|
||||||
|
|
||||||
for (i = completed._added_tasks.begin (); i != completed._added_tasks.end (); ++i)
|
for (auto& task : completed._added_tasks)
|
||||||
_changes.push_back (*i);
|
_changes.push_back (task);
|
||||||
|
|
||||||
for (i = completed._modified_tasks.begin (); i != completed._modified_tasks.end (); ++i)
|
for (auto& task : completed._modified_tasks)
|
||||||
_changes.push_back (*i);
|
_changes.push_back (task);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -842,8 +808,7 @@ void TDB2::revert_pending (
|
|||||||
std::string uuid_att = "uuid:\"" + uuid + "\"";
|
std::string uuid_att = "uuid:\"" + uuid + "\"";
|
||||||
|
|
||||||
// is 'current' in pending?
|
// is 'current' in pending?
|
||||||
std::vector <std::string>::iterator task;
|
for (auto task = p.begin (); task != p.end (); ++task)
|
||||||
for (task = p.begin (); task != p.end (); ++task)
|
|
||||||
{
|
{
|
||||||
if (task->find (uuid_att) != std::string::npos)
|
if (task->find (uuid_att) != std::string::npos)
|
||||||
{
|
{
|
||||||
@@ -877,8 +842,7 @@ void TDB2::revert_completed (
|
|||||||
std::string uuid_att = "uuid:\"" + uuid + "\"";
|
std::string uuid_att = "uuid:\"" + uuid + "\"";
|
||||||
|
|
||||||
// is 'current' in completed?
|
// is 'current' in completed?
|
||||||
std::vector <std::string>::iterator task;
|
for (auto task = c.begin (); task != c.end (); ++task)
|
||||||
for (task = c.begin (); task != c.end (); ++task)
|
|
||||||
{
|
{
|
||||||
if (task->find (uuid_att) != std::string::npos)
|
if (task->find (uuid_att) != std::string::npos)
|
||||||
{
|
{
|
||||||
@@ -927,8 +891,7 @@ void TDB2::revert_backlog (
|
|||||||
std::string uuid_att = "\"uuid\":\"" + uuid + "\"";
|
std::string uuid_att = "\"uuid\":\"" + uuid + "\"";
|
||||||
|
|
||||||
bool found = false;
|
bool found = false;
|
||||||
std::vector <std::string>::reverse_iterator task;
|
for (auto task = b.rbegin (); task != b.rend (); ++task)
|
||||||
for (task = b.rbegin (); task != b.rend (); ++task)
|
|
||||||
{
|
{
|
||||||
if (task->find (uuid_att) != std::string::npos)
|
if (task->find (uuid_att) != std::string::npos)
|
||||||
{
|
{
|
||||||
@@ -995,59 +958,56 @@ void TDB2::show_diff (
|
|||||||
Task before (prior);
|
Task before (prior);
|
||||||
|
|
||||||
std::vector <std::string> beforeAtts;
|
std::vector <std::string> beforeAtts;
|
||||||
std::map <std::string, std::string>::iterator att;
|
for (auto& att : before)
|
||||||
for (att = before.begin (); att != before.end (); ++att)
|
beforeAtts.push_back (att.first);
|
||||||
beforeAtts.push_back (att->first);
|
|
||||||
|
|
||||||
std::vector <std::string> afterAtts;
|
std::vector <std::string> afterAtts;
|
||||||
for (att = after.begin (); att != after.end (); ++att)
|
for (auto& att : after)
|
||||||
afterAtts.push_back (att->first);
|
afterAtts.push_back (att.first);
|
||||||
|
|
||||||
std::vector <std::string> beforeOnly;
|
std::vector <std::string> beforeOnly;
|
||||||
std::vector <std::string> afterOnly;
|
std::vector <std::string> afterOnly;
|
||||||
listDiff (beforeAtts, afterAtts, beforeOnly, afterOnly);
|
listDiff (beforeAtts, afterAtts, beforeOnly, afterOnly);
|
||||||
|
|
||||||
int row;
|
int row;
|
||||||
std::vector <std::string>::iterator name;
|
for (auto& name : beforeOnly)
|
||||||
for (name = beforeOnly.begin (); name != beforeOnly.end (); ++name)
|
|
||||||
{
|
{
|
||||||
row = view.addRow ();
|
row = view.addRow ();
|
||||||
view.set (row, 0, *name);
|
view.set (row, 0, name);
|
||||||
view.set (row, 1, renderAttribute (*name, before.get (*name)), color_red);
|
view.set (row, 1, renderAttribute (name, before.get (name)), color_red);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (att = before.begin (); att != before.end (); ++att)
|
for (auto& att : before)
|
||||||
{
|
{
|
||||||
std::string priorValue = before.get (att->first);
|
std::string priorValue = before.get (att.first);
|
||||||
std::string currentValue = after.get (att->first);
|
std::string currentValue = after.get (att.first);
|
||||||
|
|
||||||
if (currentValue != "")
|
if (currentValue != "")
|
||||||
{
|
{
|
||||||
row = view.addRow ();
|
row = view.addRow ();
|
||||||
view.set (row, 0, att->first);
|
view.set (row, 0, att.first);
|
||||||
view.set (row, 1, renderAttribute (att->first, priorValue),
|
view.set (row, 1, renderAttribute (att.first, priorValue),
|
||||||
(priorValue != currentValue ? color_red : Color ()));
|
(priorValue != currentValue ? color_red : Color ()));
|
||||||
view.set (row, 2, renderAttribute (att->first, currentValue),
|
view.set (row, 2, renderAttribute (att.first, currentValue),
|
||||||
(priorValue != currentValue ? color_green : Color ()));
|
(priorValue != currentValue ? color_green : Color ()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (name = afterOnly.begin (); name != afterOnly.end (); ++name)
|
for (auto& name : afterOnly)
|
||||||
{
|
{
|
||||||
row = view.addRow ();
|
row = view.addRow ();
|
||||||
view.set (row, 0, *name);
|
view.set (row, 0, name);
|
||||||
view.set (row, 2, renderAttribute (*name, after.get (*name)), color_green);
|
view.set (row, 2, renderAttribute (name, after.get (name)), color_green);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int row;
|
int row;
|
||||||
std::map <std::string, std::string>::iterator att;
|
for (auto& att : after)
|
||||||
for (att = after.begin (); att != after.end (); ++att)
|
|
||||||
{
|
{
|
||||||
row = view.addRow ();
|
row = view.addRow ();
|
||||||
view.set (row, 0, att->first);
|
view.set (row, 0, att.first);
|
||||||
view.set (row, 2, renderAttribute (att->first, after.get (att->first)), color_green);
|
view.set (row, 2, renderAttribute (att.first, after.get (att.first)), color_green);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1101,14 +1061,13 @@ void TDB2::show_diff (
|
|||||||
std::vector <std::string> all = context.getColumns ();
|
std::vector <std::string> all = context.getColumns ();
|
||||||
|
|
||||||
// Now factor in the annotation attributes.
|
// Now factor in the annotation attributes.
|
||||||
Task::iterator it;
|
for (auto& it : before)
|
||||||
for (it = before.begin (); it != before.end (); ++it)
|
if (it.first.substr (0, 11) == "annotation_")
|
||||||
if (it->first.substr (0, 11) == "annotation_")
|
all.push_back (it.first);
|
||||||
all.push_back (it->first);
|
|
||||||
|
|
||||||
for (it = after.begin (); it != after.end (); ++it)
|
for (auto& it : after)
|
||||||
if (it->first.substr (0, 11) == "annotation_")
|
if (it.first.substr (0, 11) == "annotation_")
|
||||||
all.push_back (it->first);
|
all.push_back (it.first);
|
||||||
|
|
||||||
// Now render all the attributes.
|
// Now render all the attributes.
|
||||||
std::sort (all.begin (), all.end ());
|
std::sort (all.begin (), all.end ());
|
||||||
@@ -1116,19 +1075,18 @@ void TDB2::show_diff (
|
|||||||
std::string before_att;
|
std::string before_att;
|
||||||
std::string after_att;
|
std::string after_att;
|
||||||
std::string last_att;
|
std::string last_att;
|
||||||
std::vector <std::string>::iterator a;
|
for (auto& a : all)
|
||||||
for (a = all.begin (); a != all.end (); ++a)
|
|
||||||
{
|
{
|
||||||
if (*a != last_att) // Skip duplicates.
|
if (a != last_att) // Skip duplicates.
|
||||||
{
|
{
|
||||||
last_att = *a;
|
last_att = a;
|
||||||
|
|
||||||
before_att = before.get (*a);
|
before_att = before.get (a);
|
||||||
after_att = after.get (*a);
|
after_att = after.get (a);
|
||||||
|
|
||||||
// Don't report different uuid.
|
// Don't report different uuid.
|
||||||
// Show nothing if values are the unchanged.
|
// Show nothing if values are the unchanged.
|
||||||
if (*a == "uuid" ||
|
if (a == "uuid" ||
|
||||||
before_att == after_att)
|
before_att == after_att)
|
||||||
{
|
{
|
||||||
// Show nothing - no point displaying that which did not change.
|
// Show nothing - no point displaying that which did not change.
|
||||||
@@ -1142,21 +1100,21 @@ void TDB2::show_diff (
|
|||||||
else if (before_att != "" && after_att == "")
|
else if (before_att != "" && after_att == "")
|
||||||
{
|
{
|
||||||
row = view.addRow ();
|
row = view.addRow ();
|
||||||
view.set (row, 0, "-" + *a + ":", color_red);
|
view.set (row, 0, "-" + a + ":", color_red);
|
||||||
view.set (row, 1, before_att, color_red);
|
view.set (row, 1, before_att, color_red);
|
||||||
|
|
||||||
row = view.addRow ();
|
row = view.addRow ();
|
||||||
view.set (row, 0, "+" + *a + ":", color_green);
|
view.set (row, 0, "+" + a + ":", color_green);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attribute added.
|
// Attribute added.
|
||||||
else if (before_att == "" && after_att != "")
|
else if (before_att == "" && after_att != "")
|
||||||
{
|
{
|
||||||
row = view.addRow ();
|
row = view.addRow ();
|
||||||
view.set (row, 0, "-" + *a + ":", color_red);
|
view.set (row, 0, "-" + a + ":", color_red);
|
||||||
|
|
||||||
row = view.addRow ();
|
row = view.addRow ();
|
||||||
view.set (row, 0, "+" + *a + ":", color_green);
|
view.set (row, 0, "+" + a + ":", color_green);
|
||||||
view.set (row, 1, after_att, color_green);
|
view.set (row, 1, after_att, color_green);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1164,11 +1122,11 @@ void TDB2::show_diff (
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
row = view.addRow ();
|
row = view.addRow ();
|
||||||
view.set (row, 0, "-" + *a + ":", color_red);
|
view.set (row, 0, "-" + a + ":", color_red);
|
||||||
view.set (row, 1, before_att, color_red);
|
view.set (row, 1, before_att, color_red);
|
||||||
|
|
||||||
row = view.addRow ();
|
row = view.addRow ();
|
||||||
view.set (row, 0, "+" + *a + ":", color_green);
|
view.set (row, 0, "+" + a + ":", color_green);
|
||||||
view.set (row, 1, after_att, color_green);
|
view.set (row, 1, after_att, color_green);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1198,10 +1156,10 @@ int TDB2::gc ()
|
|||||||
// Allowed as an override, but not recommended.
|
// Allowed as an override, but not recommended.
|
||||||
if (context.config.getBoolean ("gc"))
|
if (context.config.getBoolean ("gc"))
|
||||||
{
|
{
|
||||||
std::vector <Task> pending_tasks = pending.get_tasks ();
|
auto pending_tasks = pending.get_tasks ();
|
||||||
|
|
||||||
// TODO Thread.
|
// TODO Thread.
|
||||||
std::vector <Task> completed_tasks = completed.get_tasks ();
|
auto completed_tasks = completed.get_tasks ();
|
||||||
|
|
||||||
// TODO Assume pending < completed, therefore there is room here to process
|
// TODO Assume pending < completed, therefore there is room here to process
|
||||||
// data before joining with the completed.data thread.
|
// data before joining with the completed.data thread.
|
||||||
@@ -1218,32 +1176,29 @@ int TDB2::gc ()
|
|||||||
// completed, or need to be 'woken'.
|
// completed, or need to be 'woken'.
|
||||||
Date now;
|
Date now;
|
||||||
std::string status;
|
std::string status;
|
||||||
std::vector <Task>::iterator task;
|
for (auto& task : pending_tasks)
|
||||||
for (task = pending_tasks.begin ();
|
|
||||||
task != pending_tasks.end ();
|
|
||||||
++task)
|
|
||||||
{
|
{
|
||||||
status = task->get ("status");
|
status = task.get ("status");
|
||||||
if (status == "pending" ||
|
if (status == "pending" ||
|
||||||
status == "recurring")
|
status == "recurring")
|
||||||
{
|
{
|
||||||
pending_tasks_after.push_back (*task);
|
pending_tasks_after.push_back (task);
|
||||||
}
|
}
|
||||||
else if (status == "waiting")
|
else if (status == "waiting")
|
||||||
{
|
{
|
||||||
Date wait (task->get_date ("wait"));
|
Date wait (task.get_date ("wait"));
|
||||||
if (wait < now)
|
if (wait < now)
|
||||||
{
|
{
|
||||||
task->set ("status", "pending");
|
task.set ("status", "pending");
|
||||||
task->remove ("wait");
|
task.remove ("wait");
|
||||||
pending_changes = true;
|
pending_changes = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
pending_tasks_after.push_back (*task);
|
pending_tasks_after.push_back (task);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
completed_tasks_after.push_back (*task);
|
completed_tasks_after.push_back (task);
|
||||||
pending_changes = true;
|
pending_changes = true;
|
||||||
completed_changes = true;
|
completed_changes = true;
|
||||||
}
|
}
|
||||||
@@ -1256,35 +1211,33 @@ int TDB2::gc ()
|
|||||||
|
|
||||||
// Scan all completed tasks, looking for any that need to be relocated to
|
// Scan all completed tasks, looking for any that need to be relocated to
|
||||||
// pending.
|
// pending.
|
||||||
for (task = completed_tasks.begin ();
|
for (auto& task : completed_tasks)
|
||||||
task != completed_tasks.end ();
|
|
||||||
++task)
|
|
||||||
{
|
{
|
||||||
status = task->get ("status");
|
status = task.get ("status");
|
||||||
if (status == "pending" ||
|
if (status == "pending" ||
|
||||||
status == "recurring")
|
status == "recurring")
|
||||||
{
|
{
|
||||||
pending_tasks_after.push_back (*task);
|
pending_tasks_after.push_back (task);
|
||||||
pending_changes = true;
|
pending_changes = true;
|
||||||
completed_changes = true;
|
completed_changes = true;
|
||||||
}
|
}
|
||||||
else if (status == "waiting")
|
else if (status == "waiting")
|
||||||
{
|
{
|
||||||
Date wait (task->get_date ("wait"));
|
Date wait (task.get_date ("wait"));
|
||||||
if (wait < now)
|
if (wait < now)
|
||||||
{
|
{
|
||||||
task->set ("status", "pending");
|
task.set ("status", "pending");
|
||||||
task->remove ("wait");
|
task.remove ("wait");
|
||||||
pending_tasks_after.push_back (*task);
|
pending_tasks_after.push_back (task);
|
||||||
pending_changes = true;
|
pending_changes = true;
|
||||||
completed_changes = true;
|
completed_changes = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
pending_tasks_after.push_back (*task);
|
pending_tasks_after.push_back (task);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
completed_tasks_after.push_back (*task);
|
completed_tasks_after.push_back (task);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1296,12 +1249,8 @@ int TDB2::gc ()
|
|||||||
pending._loaded_tasks = true;
|
pending._loaded_tasks = true;
|
||||||
_id = 1;
|
_id = 1;
|
||||||
|
|
||||||
for (task = pending._tasks.begin ();
|
for (auto& task : pending._tasks)
|
||||||
task != pending._tasks.end ();
|
task.id = _id++;
|
||||||
++task)
|
|
||||||
{
|
|
||||||
task->id = _id++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note: deliberately no commit.
|
// Note: deliberately no commit.
|
||||||
}
|
}
|
||||||
@@ -1347,9 +1296,8 @@ const std::vector <Task> TDB2::all_tasks ()
|
|||||||
completed._added_tasks.size ());
|
completed._added_tasks.size ());
|
||||||
extra = completed.get_tasks ();
|
extra = completed.get_tasks ();
|
||||||
|
|
||||||
std::vector <Task>::iterator task;
|
for (auto& task : extra)
|
||||||
for (task = extra.begin (); task != extra.end (); ++task)
|
all.push_back (task);
|
||||||
all.push_back (*task);
|
|
||||||
|
|
||||||
return all;
|
return all;
|
||||||
}
|
}
|
||||||
@@ -1390,21 +1338,20 @@ const std::vector <Task> TDB2::siblings (Task& task)
|
|||||||
if (! pending._loaded_tasks)
|
if (! pending._loaded_tasks)
|
||||||
pending.load_tasks ();
|
pending.load_tasks ();
|
||||||
|
|
||||||
std::vector <Task>::iterator i;
|
for (auto& i : pending._tasks)
|
||||||
for (i = pending._tasks.begin (); i != pending._tasks.end (); ++i)
|
|
||||||
{
|
{
|
||||||
// Do not include self in results.
|
// Do not include self in results.
|
||||||
if (i->id != task.id)
|
if (i.id != task.id)
|
||||||
{
|
{
|
||||||
// Do not include completed or deleted tasks.
|
// Do not include completed or deleted tasks.
|
||||||
if (i->getStatus () != Task::completed &&
|
if (i.getStatus () != Task::completed &&
|
||||||
i->getStatus () != Task::deleted)
|
i.getStatus () != Task::deleted)
|
||||||
{
|
{
|
||||||
// If task has the same parent, it is a sibling.
|
// If task has the same parent, it is a sibling.
|
||||||
if (i->has ("parent") &&
|
if (i.has ("parent") &&
|
||||||
i->get ("parent") == parent)
|
i.get ("parent") == parent)
|
||||||
{
|
{
|
||||||
results.push_back (*i);
|
results.push_back (i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1424,19 +1371,18 @@ const std::vector <Task> TDB2::children (Task& task)
|
|||||||
if (! pending._loaded_tasks)
|
if (! pending._loaded_tasks)
|
||||||
pending.load_tasks ();
|
pending.load_tasks ();
|
||||||
|
|
||||||
std::vector <Task>::iterator i;
|
for (auto& i : pending._tasks)
|
||||||
for (i = pending._tasks.begin (); i != pending._tasks.end (); ++i)
|
|
||||||
{
|
{
|
||||||
// Do not include self in results.
|
// Do not include self in results.
|
||||||
if (i->id != task.id)
|
if (i.id != task.id)
|
||||||
{
|
{
|
||||||
// Do not include completed or deleted tasks.
|
// Do not include completed or deleted tasks.
|
||||||
if (i->getStatus () != Task::completed &&
|
if (i.getStatus () != Task::completed &&
|
||||||
i->getStatus () != Task::deleted)
|
i.getStatus () != Task::deleted)
|
||||||
{
|
{
|
||||||
// If task has the same parent, it is a sibling.
|
// If task has the same parent, it is a sibling.
|
||||||
if (i->get ("parent") == parent)
|
if (i.get ("parent") == parent)
|
||||||
results.push_back (*i);
|
results.push_back (i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
322
src/Task.cpp
322
src/Task.cpp
@@ -130,10 +130,9 @@ bool Task::operator== (const Task& other)
|
|||||||
if (size () != other.size ())
|
if (size () != other.size ())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Task::iterator i;
|
for (auto& i : *this)
|
||||||
for (i = this->begin (); i != this->end (); ++i)
|
if (i.first != "uuid" &&
|
||||||
if (i->first != "uuid" &&
|
i.second != other.get (i.first))
|
||||||
i->second != other.get (i->first))
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -194,7 +193,7 @@ void Task::setAsNow (const std::string& att)
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
bool Task::has (const std::string& name) const
|
bool Task::has (const std::string& name) const
|
||||||
{
|
{
|
||||||
Task::const_iterator i = this->find (name);
|
auto i = this->find (name);
|
||||||
if (i != this->end ())
|
if (i != this->end ())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@@ -205,8 +204,7 @@ bool Task::has (const std::string& name) const
|
|||||||
std::vector <std::string> Task::all ()
|
std::vector <std::string> Task::all ()
|
||||||
{
|
{
|
||||||
std::vector <std::string> all;
|
std::vector <std::string> all;
|
||||||
Task::iterator i;
|
for (auto i = this->begin (); i != this->end (); ++i)
|
||||||
for (i = this->begin (); i != this->end (); ++i)
|
|
||||||
all.push_back (i->first);
|
all.push_back (i->first);
|
||||||
|
|
||||||
return all;
|
return all;
|
||||||
@@ -215,7 +213,7 @@ std::vector <std::string> Task::all ()
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
const std::string Task::get (const std::string& name) const
|
const std::string Task::get (const std::string& name) const
|
||||||
{
|
{
|
||||||
Task::const_iterator i = this->find (name);
|
auto i = this->find (name);
|
||||||
if (i != this->end ())
|
if (i != this->end ())
|
||||||
return i->second;
|
return i->second;
|
||||||
|
|
||||||
@@ -225,7 +223,7 @@ const std::string Task::get (const std::string& name) const
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
const std::string& Task::get_ref (const std::string& name) const
|
const std::string& Task::get_ref (const std::string& name) const
|
||||||
{
|
{
|
||||||
Task::const_iterator i = this->find (name);
|
auto i = this->find (name);
|
||||||
if (i != this->end ())
|
if (i != this->end ())
|
||||||
return i->second;
|
return i->second;
|
||||||
|
|
||||||
@@ -235,7 +233,7 @@ const std::string& Task::get_ref (const std::string& name) const
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
int Task::get_int (const std::string& name) const
|
int Task::get_int (const std::string& name) const
|
||||||
{
|
{
|
||||||
Task::const_iterator i = this->find (name);
|
auto i = this->find (name);
|
||||||
if (i != this->end ())
|
if (i != this->end ())
|
||||||
return strtol (i->second.c_str (), NULL, 10);
|
return strtol (i->second.c_str (), NULL, 10);
|
||||||
|
|
||||||
@@ -245,7 +243,7 @@ int Task::get_int (const std::string& name) const
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
unsigned long Task::get_ulong (const std::string& name) const
|
unsigned long Task::get_ulong (const std::string& name) const
|
||||||
{
|
{
|
||||||
Task::const_iterator i = this->find (name);
|
auto i = this->find (name);
|
||||||
if (i != this->end ())
|
if (i != this->end ())
|
||||||
return strtoul (i->second.c_str (), NULL, 10);
|
return strtoul (i->second.c_str (), NULL, 10);
|
||||||
|
|
||||||
@@ -255,7 +253,7 @@ unsigned long Task::get_ulong (const std::string& name) const
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
float Task::get_float (const std::string& name) const
|
float Task::get_float (const std::string& name) const
|
||||||
{
|
{
|
||||||
Task::const_iterator i = this->find (name);
|
auto i = this->find (name);
|
||||||
if (i != this->end ())
|
if (i != this->end ())
|
||||||
return strtof (i->second.c_str (), NULL);
|
return strtof (i->second.c_str (), NULL);
|
||||||
|
|
||||||
@@ -265,7 +263,7 @@ float Task::get_float (const std::string& name) const
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
time_t Task::get_date (const std::string& name) const
|
time_t Task::get_date (const std::string& name) const
|
||||||
{
|
{
|
||||||
Task::const_iterator i = this->find (name);
|
auto i = this->find (name);
|
||||||
if (i != this->end ())
|
if (i != this->end ())
|
||||||
return (time_t) strtoul (i->second.c_str (), NULL, 10);
|
return (time_t) strtoul (i->second.c_str (), NULL, 10);
|
||||||
|
|
||||||
@@ -291,8 +289,8 @@ void Task::set (const std::string& name, int value)
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void Task::remove (const std::string& name)
|
void Task::remove (const std::string& name)
|
||||||
{
|
{
|
||||||
Task::iterator it;
|
auto it = this->find (name);
|
||||||
if ((it = this->find (name)) != this->end ())
|
if (it != this->end ())
|
||||||
{
|
{
|
||||||
this->erase (it);
|
this->erase (it);
|
||||||
recalc_urgency = true;
|
recalc_urgency = true;
|
||||||
@@ -606,66 +604,60 @@ void Task::parseJSON (const std::string& line)
|
|||||||
json::object* root_obj = (json::object*)root;
|
json::object* root_obj = (json::object*)root;
|
||||||
|
|
||||||
// For each object element...
|
// For each object element...
|
||||||
json_object_iter i;
|
for (auto& i : root_obj->_data)
|
||||||
for (i = root_obj->_data.begin ();
|
|
||||||
i != root_obj->_data.end ();
|
|
||||||
++i)
|
|
||||||
{
|
{
|
||||||
// If the attribute is a recognized column.
|
// If the attribute is a recognized column.
|
||||||
std::string type = Task::attributes[i->first];
|
std::string type = Task::attributes[i.first];
|
||||||
if (type != "")
|
if (type != "")
|
||||||
{
|
{
|
||||||
// Any specified id is ignored.
|
// Any specified id is ignored.
|
||||||
if (i->first == "id")
|
if (i.first == "id")
|
||||||
;
|
;
|
||||||
|
|
||||||
// Urgency, if present, is ignored.
|
// Urgency, if present, is ignored.
|
||||||
else if (i->first == "urgency")
|
else if (i.first == "urgency")
|
||||||
;
|
;
|
||||||
|
|
||||||
// TW-1274 Standardization.
|
// TW-1274 Standardization.
|
||||||
else if (i->first == "modification")
|
else if (i.first == "modification")
|
||||||
{
|
{
|
||||||
Date d (unquoteText (i->second->dump ()));
|
Date d (unquoteText (i.second->dump ()));
|
||||||
set ("modified", d.toEpochString ());
|
set ("modified", d.toEpochString ());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dates are converted from ISO to epoch.
|
// Dates are converted from ISO to epoch.
|
||||||
else if (type == "date")
|
else if (type == "date")
|
||||||
{
|
{
|
||||||
std::string text = unquoteText (i->second->dump ());
|
std::string text = unquoteText (i.second->dump ());
|
||||||
Date d (text);
|
Date d (text);
|
||||||
set (i->first, text == "" ? "" : d.toEpochString ());
|
set (i.first, text == "" ? "" : d.toEpochString ());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tags are an array of JSON strings.
|
// Tags are an array of JSON strings.
|
||||||
else if (i->first == "tags" && i->second->type() == json::j_array)
|
else if (i.first == "tags" && i.second->type() == json::j_array)
|
||||||
{
|
{
|
||||||
json::array* tags = (json::array*)i->second;
|
json::array* tags = (json::array*)i.second;
|
||||||
json_array_iter t;
|
for (auto& t : tags->_data)
|
||||||
for (t = tags->_data.begin ();
|
|
||||||
t != tags->_data.end ();
|
|
||||||
++t)
|
|
||||||
{
|
{
|
||||||
json::string* tag = (json::string*)*t;
|
json::string* tag = (json::string*)t;
|
||||||
addTag (tag->_data);
|
addTag (tag->_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// This is a temporary measure to allow Mirakel sync, and will be removed
|
// This is a temporary measure to allow Mirakel sync, and will be removed
|
||||||
// in a future release.
|
// in a future release.
|
||||||
else if (i->first == "tags" && i->second->type() == json::j_string)
|
else if (i.first == "tags" && i.second->type() == json::j_string)
|
||||||
{
|
{
|
||||||
json::string* tag = (json::string*)i->second;
|
json::string* tag = (json::string*)i.second;
|
||||||
addTag (tag->_data);
|
addTag (tag->_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Strings are decoded.
|
// Strings are decoded.
|
||||||
else if (type == "string")
|
else if (type == "string")
|
||||||
set (i->first, json::decode (unquoteText (i->second->dump ())));
|
set (i.first, json::decode (unquoteText (i.second->dump ())));
|
||||||
|
|
||||||
// Other types are simply added.
|
// Other types are simply added.
|
||||||
else
|
else
|
||||||
set (i->first, unquoteText (i->second->dump ()));
|
set (i.first, unquoteText (i.second->dump ()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// UDA orphans and annotations do not have columns.
|
// UDA orphans and annotations do not have columns.
|
||||||
@@ -673,17 +665,14 @@ void Task::parseJSON (const std::string& line)
|
|||||||
{
|
{
|
||||||
// Annotations are an array of JSON objects with 'entry' and
|
// Annotations are an array of JSON objects with 'entry' and
|
||||||
// 'description' values and must be converted.
|
// 'description' values and must be converted.
|
||||||
if (i->first == "annotations")
|
if (i.first == "annotations")
|
||||||
{
|
{
|
||||||
std::map <std::string, std::string> annos;
|
std::map <std::string, std::string> annos;
|
||||||
|
|
||||||
json::array* atts = (json::array*)i->second;
|
json::array* atts = (json::array*)i.second;
|
||||||
json_array_iter annotations;
|
for (auto& annotations : atts->_data)
|
||||||
for (annotations = atts->_data.begin ();
|
|
||||||
annotations != atts->_data.end ();
|
|
||||||
++annotations)
|
|
||||||
{
|
{
|
||||||
json::object* annotation = (json::object*)*annotations;
|
json::object* annotation = (json::object*)annotations;
|
||||||
json::string* when = (json::string*)annotation->_data["entry"];
|
json::string* when = (json::string*)annotation->_data["entry"];
|
||||||
json::string* what = (json::string*)annotation->_data["description"];
|
json::string* what = (json::string*)annotation->_data["description"];
|
||||||
|
|
||||||
@@ -706,13 +695,13 @@ void Task::parseJSON (const std::string& line)
|
|||||||
#ifdef PRODUCT_TASKWARRIOR
|
#ifdef PRODUCT_TASKWARRIOR
|
||||||
std::stringstream message;
|
std::stringstream message;
|
||||||
message << "Task::parseJSON found orphan '"
|
message << "Task::parseJSON found orphan '"
|
||||||
<< i->first
|
<< i.first
|
||||||
<< "' with value '"
|
<< "' with value '"
|
||||||
<< i->second
|
<< i.second
|
||||||
<< "' --> preserved\n";
|
<< "' --> preserved\n";
|
||||||
context.debug (message.str ());
|
context.debug (message.str ());
|
||||||
#endif
|
#endif
|
||||||
set (i->first, json::decode (unquoteText (i->second->dump ())));
|
set (i.first, json::decode (unquoteText (i.second->dump ())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -761,15 +750,14 @@ std::string Task::composeF4 () const
|
|||||||
std::string ff4 = "[";
|
std::string ff4 = "[";
|
||||||
|
|
||||||
bool first = true;
|
bool first = true;
|
||||||
Task::const_iterator it;
|
for (auto it : *this)
|
||||||
for (it = this->begin (); it != this->end (); ++it)
|
|
||||||
{
|
{
|
||||||
if (it->second != "")
|
if (it.second != "")
|
||||||
{
|
{
|
||||||
ff4 += (first ? "" : " ")
|
ff4 += (first ? "" : " ")
|
||||||
+ it->first
|
+ it.first
|
||||||
+ ":\""
|
+ ":\""
|
||||||
+ encode (json::encode (it->second))
|
+ encode (json::encode (it.second))
|
||||||
+ "\"";
|
+ "\"";
|
||||||
|
|
||||||
first = false;
|
first = false;
|
||||||
@@ -793,33 +781,32 @@ std::string Task::composeJSON (bool decorate /*= false*/) const
|
|||||||
|
|
||||||
// First the non-annotations.
|
// First the non-annotations.
|
||||||
int attributes_written = 0;
|
int attributes_written = 0;
|
||||||
Task::const_iterator i;
|
for (auto& i : *this)
|
||||||
for (i = this->begin (); i != this->end (); ++i)
|
|
||||||
{
|
{
|
||||||
// Annotations are not written out here.
|
// Annotations are not written out here.
|
||||||
if (i->first.substr (0, 11) == "annotation_")
|
if (i.first.substr (0, 11) == "annotation_")
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// If value is an empty string, do not ever output it
|
// If value is an empty string, do not ever output it
|
||||||
if (i->second == "")
|
if (i.second == "")
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (attributes_written)
|
if (attributes_written)
|
||||||
out << ",";
|
out << ",";
|
||||||
|
|
||||||
std::string type = Task::attributes[i->first];
|
std::string type = Task::attributes[i.first];
|
||||||
if (type == "")
|
if (type == "")
|
||||||
type = "string";
|
type = "string";
|
||||||
|
|
||||||
// Date fields are written as ISO 8601.
|
// Date fields are written as ISO 8601.
|
||||||
if (type == "date")
|
if (type == "date")
|
||||||
{
|
{
|
||||||
Date d (i->second);
|
Date d (i.second);
|
||||||
out << "\""
|
out << "\""
|
||||||
<< (i->first == "modification" ? "modified" : i->first)
|
<< (i.first == "modification" ? "modified" : i.first)
|
||||||
<< "\":\""
|
<< "\":\""
|
||||||
// Date was deleted, do not export parsed empty string
|
// Date was deleted, do not export parsed empty string
|
||||||
<< (i->second == "" ? "" : d.toISO ())
|
<< (i.second == "" ? "" : d.toISO ())
|
||||||
<< "\"";
|
<< "\"";
|
||||||
|
|
||||||
++attributes_written;
|
++attributes_written;
|
||||||
@@ -828,23 +815,22 @@ std::string Task::composeJSON (bool decorate /*= false*/) const
|
|||||||
else if (type == "numeric")
|
else if (type == "numeric")
|
||||||
{
|
{
|
||||||
out << "\""
|
out << "\""
|
||||||
<< i->first
|
<< i.first
|
||||||
<< "\":"
|
<< "\":"
|
||||||
<< i->second;
|
<< i.second;
|
||||||
|
|
||||||
++attributes_written;
|
++attributes_written;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tags are converted to an array.
|
// Tags are converted to an array.
|
||||||
else if (i->first == "tags")
|
else if (i.first == "tags")
|
||||||
{
|
{
|
||||||
std::vector <std::string> tags;
|
std::vector <std::string> tags;
|
||||||
split (tags, i->second, ',');
|
split (tags, i.second, ',');
|
||||||
|
|
||||||
out << "\"tags\":[";
|
out << "\"tags\":[";
|
||||||
|
|
||||||
std::vector <std::string>::iterator i;
|
for (auto i = tags.begin (); i != tags.end (); ++i)
|
||||||
for (i = tags.begin (); i != tags.end (); ++i)
|
|
||||||
{
|
{
|
||||||
if (i != tags.begin ())
|
if (i != tags.begin ())
|
||||||
out << ",";
|
out << ",";
|
||||||
@@ -861,9 +847,9 @@ std::string Task::composeJSON (bool decorate /*= false*/) const
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
out << "\""
|
out << "\""
|
||||||
<< i->first
|
<< i.first
|
||||||
<< "\":\""
|
<< "\":\""
|
||||||
<< json::encode (i->second)
|
<< json::encode (i.second)
|
||||||
<< "\"";
|
<< "\"";
|
||||||
|
|
||||||
++attributes_written;
|
++attributes_written;
|
||||||
@@ -877,18 +863,18 @@ std::string Task::composeJSON (bool decorate /*= false*/) const
|
|||||||
<< "\"annotations\":[";
|
<< "\"annotations\":[";
|
||||||
|
|
||||||
int annotations_written = 0;
|
int annotations_written = 0;
|
||||||
for (i = this->begin (); i != this->end (); ++i)
|
for (auto& i : *this)
|
||||||
{
|
{
|
||||||
if (i->first.substr (0, 11) == "annotation_")
|
if (i.first.substr (0, 11) == "annotation_")
|
||||||
{
|
{
|
||||||
if (annotations_written)
|
if (annotations_written)
|
||||||
out << ",";
|
out << ",";
|
||||||
|
|
||||||
Date d (i->first.substr (11));
|
Date d (i.first.substr (11));
|
||||||
out << "{\"entry\":\""
|
out << "{\"entry\":\""
|
||||||
<< d.toISO ()
|
<< d.toISO ()
|
||||||
<< "\",\"description\":\""
|
<< "\",\"description\":\""
|
||||||
<< json::encode (i->second)
|
<< json::encode (i.second)
|
||||||
<< "\"}";
|
<< "\"}";
|
||||||
|
|
||||||
++annotations_written;
|
++annotations_written;
|
||||||
@@ -943,7 +929,7 @@ void Task::addAnnotation (const std::string& description)
|
|||||||
void Task::removeAnnotations ()
|
void Task::removeAnnotations ()
|
||||||
{
|
{
|
||||||
// Erase old annotations.
|
// Erase old annotations.
|
||||||
Task::iterator i = this->begin ();
|
auto i = this->begin ();
|
||||||
while (i != this->end ())
|
while (i != this->end ())
|
||||||
{
|
{
|
||||||
if (i->first.substr (0, 11) == "annotation_")
|
if (i->first.substr (0, 11) == "annotation_")
|
||||||
@@ -963,10 +949,9 @@ void Task::getAnnotations (std::map <std::string, std::string>& annotations) con
|
|||||||
{
|
{
|
||||||
annotations.clear ();
|
annotations.clear ();
|
||||||
|
|
||||||
Task::const_iterator ci;
|
for (auto& ann : *this)
|
||||||
for (ci = this->begin (); ci != this->end (); ++ci)
|
if (ann.first.substr (0, 11) == "annotation_")
|
||||||
if (ci->first.substr (0, 11) == "annotation_")
|
annotations.insert (ann);
|
||||||
annotations.insert (*ci);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -975,9 +960,8 @@ void Task::setAnnotations (const std::map <std::string, std::string>& annotation
|
|||||||
// Erase old annotations.
|
// Erase old annotations.
|
||||||
removeAnnotations ();
|
removeAnnotations ();
|
||||||
|
|
||||||
std::map <std::string, std::string>::const_iterator ci;
|
for (auto& anno : annotations)
|
||||||
for (ci = annotations.begin (); ci != annotations.end (); ++ci)
|
this->insert (anno);
|
||||||
this->insert (*ci);
|
|
||||||
|
|
||||||
annotation_count = annotations.size ();
|
annotation_count = annotations.size ();
|
||||||
recalc_urgency = true;
|
recalc_urgency = true;
|
||||||
@@ -1031,8 +1015,7 @@ void Task::removeDependency (const std::string& uuid)
|
|||||||
std::vector <std::string> deps;
|
std::vector <std::string> deps;
|
||||||
split (deps, get ("depends"), ',');
|
split (deps, get ("depends"), ',');
|
||||||
|
|
||||||
std::vector <std::string>::iterator i;
|
auto i = std::find (deps.begin (), deps.end (), uuid);
|
||||||
i = std::find (deps.begin (), deps.end (), uuid);
|
|
||||||
if (i != deps.end ())
|
if (i != deps.end ())
|
||||||
{
|
{
|
||||||
deps.erase (i);
|
deps.erase (i);
|
||||||
@@ -1064,9 +1047,8 @@ void Task::getDependencies (std::vector <int>& all) const
|
|||||||
|
|
||||||
all.clear ();
|
all.clear ();
|
||||||
|
|
||||||
std::vector <std::string>::iterator i;
|
for (auto& dep : deps)
|
||||||
for (i = deps.begin (); i != deps.end (); ++i)
|
all.push_back (context.tdb2.pending.id (dep));
|
||||||
all.push_back (context.tdb2.pending.id (*i));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -1160,9 +1142,8 @@ void Task::addTags (const std::vector <std::string>& tags)
|
|||||||
{
|
{
|
||||||
remove ("tags");
|
remove ("tags");
|
||||||
|
|
||||||
std::vector <std::string>::const_iterator it;
|
for (auto& tag : tags)
|
||||||
for (it = tags.begin (); it != tags.end (); ++it)
|
addTag (tag);
|
||||||
addTag (*it);
|
|
||||||
|
|
||||||
recalc_urgency = true;
|
recalc_urgency = true;
|
||||||
}
|
}
|
||||||
@@ -1179,8 +1160,7 @@ void Task::removeTag (const std::string& tag)
|
|||||||
std::vector <std::string> tags;
|
std::vector <std::string> tags;
|
||||||
split (tags, get ("tags"), ',');
|
split (tags, get ("tags"), ',');
|
||||||
|
|
||||||
std::vector <std::string>::iterator i;
|
auto i = std::find (tags.begin (), tags.end (), tag);
|
||||||
i = std::find (tags.begin (), tags.end (), tag);
|
|
||||||
if (i != tags.end ())
|
if (i != tags.end ())
|
||||||
{
|
{
|
||||||
tags.erase (i);
|
tags.erase (i);
|
||||||
@@ -1198,21 +1178,19 @@ void Task::removeTag (const std::string& tag)
|
|||||||
// 'uda.<name>.type'
|
// 'uda.<name>.type'
|
||||||
void Task::getUDAs (std::vector <std::string>& names) const
|
void Task::getUDAs (std::vector <std::string>& names) const
|
||||||
{
|
{
|
||||||
Task::const_iterator it;
|
for (auto& it : *this)
|
||||||
for (it = this->begin (); it != this->end (); ++it)
|
if (context.config.get ("uda." + it.first + ".type") != "")
|
||||||
if (context.config.get ("uda." + it->first + ".type") != "")
|
names.push_back (it.first);
|
||||||
names.push_back (it->first);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// A UDA Orphan is an attribute that is not represented in context.columns.
|
// A UDA Orphan is an attribute that is not represented in context.columns.
|
||||||
void Task::getUDAOrphans (std::vector <std::string>& names) const
|
void Task::getUDAOrphans (std::vector <std::string>& names) const
|
||||||
{
|
{
|
||||||
Task::const_iterator it;
|
for (auto& it : *this)
|
||||||
for (it = this->begin (); it != this->end (); ++it)
|
if (it.first.substr (0, 11) != "annotation_")
|
||||||
if (it->first.substr (0, 11) != "annotation_")
|
if (context.columns.find (it.first) == context.columns.end ())
|
||||||
if (context.columns.find (it->first) == context.columns.end ())
|
names.push_back (it.first);
|
||||||
names.push_back (it->first);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -1257,17 +1235,16 @@ void Task::substitute (
|
|||||||
if (!done)
|
if (!done)
|
||||||
{
|
{
|
||||||
// Perform all subs on annotations.
|
// Perform all subs on annotations.
|
||||||
std::map <std::string, std::string>::iterator it;
|
for (auto& it : annotations)
|
||||||
for (it = annotations.begin (); it != annotations.end () && !done; ++it)
|
|
||||||
{
|
{
|
||||||
start.clear ();
|
start.clear ();
|
||||||
end.clear ();
|
end.clear ();
|
||||||
if (rx.match (start, end, it->second))
|
if (rx.match (start, end, it.second))
|
||||||
{
|
{
|
||||||
int skew = 0;
|
int skew = 0;
|
||||||
for (unsigned int i = 0; i < start.size () && !done; ++i)
|
for (unsigned int i = 0; i < start.size () && !done; ++i)
|
||||||
{
|
{
|
||||||
it->second.replace (start[i + skew], end[i] - start[i], to);
|
it.second.replace (start[i + skew], end[i] - start[i], to);
|
||||||
skew += to.length () - (end[i] - start[i]);
|
skew += to.length () - (end[i] - start[i]);
|
||||||
++changes;
|
++changes;
|
||||||
|
|
||||||
@@ -1304,14 +1281,13 @@ void Task::substitute (
|
|||||||
{
|
{
|
||||||
// Perform all subs on annotations.
|
// Perform all subs on annotations.
|
||||||
counter = 0;
|
counter = 0;
|
||||||
std::map <std::string, std::string>::iterator i;
|
for (auto& anno : annotations)
|
||||||
for (i = annotations.begin (); i != annotations.end () && !done; ++i)
|
|
||||||
{
|
{
|
||||||
pos = 0;
|
pos = 0;
|
||||||
skew = 0;
|
skew = 0;
|
||||||
while ((pos = ::find (i->second, from, pos, Task::searchCaseSensitive)) != std::string::npos && !done)
|
while ((pos = ::find (anno.second, from, pos, Task::searchCaseSensitive)) != std::string::npos && !done)
|
||||||
{
|
{
|
||||||
i->second.replace (pos + skew, from.length (), to);
|
anno.second.replace (pos + skew, from.length (), to);
|
||||||
skew += to.length () - from.length ();
|
skew += to.length () - from.length ();
|
||||||
|
|
||||||
pos += to.length ();
|
pos += to.length ();
|
||||||
@@ -1412,15 +1388,14 @@ void Task::validate (bool applyDefault /* = true */)
|
|||||||
// override with uda.(uda).default, if not specified.
|
// override with uda.(uda).default, if not specified.
|
||||||
// Gather a list of all UDAs with a .default value
|
// Gather a list of all UDAs with a .default value
|
||||||
std::vector <std::string> udas;
|
std::vector <std::string> udas;
|
||||||
Config::const_iterator var;
|
for (auto& var : context.config)
|
||||||
for (var = context.config.begin (); var != context.config.end (); ++var)
|
|
||||||
{
|
{
|
||||||
if (var->first.substr (0, 4) == "uda." &&
|
if (var.first.substr (0, 4) == "uda." &&
|
||||||
var->first.find (".default") != std::string::npos)
|
var.first.find (".default") != std::string::npos)
|
||||||
{
|
{
|
||||||
std::string::size_type period = var->first.find ('.', 4);
|
std::string::size_type period = var.first.find ('.', 4);
|
||||||
if (period != std::string::npos)
|
if (period != std::string::npos)
|
||||||
udas.push_back (var->first.substr (4, period - 4));
|
udas.push_back (var.first.substr (4, period - 4));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1428,14 +1403,13 @@ void Task::validate (bool applyDefault /* = true */)
|
|||||||
{
|
{
|
||||||
// For each of those, setup the default value on the task now,
|
// For each of those, setup the default value on the task now,
|
||||||
// of course only if we don't have one on the command line already
|
// of course only if we don't have one on the command line already
|
||||||
std::vector <std::string>::iterator uda;
|
for (auto& uda : udas)
|
||||||
for (uda = udas.begin (); uda != udas.end (); ++uda)
|
|
||||||
{
|
{
|
||||||
std::string defVal= context.config.get ("uda." + *uda + ".default");
|
std::string defVal= context.config.get ("uda." + uda + ".default");
|
||||||
|
|
||||||
// If the default is empty, or we already have a value, skip it
|
// If the default is empty, or we already have a value, skip it
|
||||||
if (defVal != "" && get (*uda) == "")
|
if (defVal != "" && get (uda) == "")
|
||||||
set (*uda, defVal);
|
set (uda, defVal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1650,64 +1624,63 @@ float Task::urgency_c () const
|
|||||||
value += fabsf (Task::urgencyInheritCoefficient) > epsilon ? (urgency_inherit () * Task::urgencyInheritCoefficient) : 0.0;
|
value += fabsf (Task::urgencyInheritCoefficient) > epsilon ? (urgency_inherit () * Task::urgencyInheritCoefficient) : 0.0;
|
||||||
|
|
||||||
// Tag- and project-specific coefficients.
|
// Tag- and project-specific coefficients.
|
||||||
std::map <std::string, float>::iterator var;
|
for (auto& var : Task::coefficients)
|
||||||
for (var = Task::coefficients.begin (); var != Task::coefficients.end (); ++var)
|
|
||||||
{
|
{
|
||||||
if (fabs (var->second) > epsilon)
|
if (fabs (var.second) > epsilon)
|
||||||
{
|
{
|
||||||
if (var->first.substr (0, 13) == "urgency.user.")
|
if (var.first.substr (0, 13) == "urgency.user.")
|
||||||
{
|
{
|
||||||
// urgency.user.project.<project>.coefficient
|
// urgency.user.project.<project>.coefficient
|
||||||
std::string::size_type end = std::string::npos;
|
std::string::size_type end = std::string::npos;
|
||||||
if (var->first.substr (13, 8) == "project." &&
|
if (var.first.substr (13, 8) == "project." &&
|
||||||
(end = var->first.find (".coefficient")) != std::string::npos)
|
(end = var.first.find (".coefficient")) != std::string::npos)
|
||||||
{
|
{
|
||||||
std::string project = var->first.substr (21, end - 21);
|
std::string project = var.first.substr (21, end - 21);
|
||||||
|
|
||||||
if (get ("project").find (project) == 0)
|
if (get ("project").find (project) == 0)
|
||||||
value += var->second;
|
value += var.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
// urgency.user.tag.<tag>.coefficient
|
// urgency.user.tag.<tag>.coefficient
|
||||||
if (var->first.substr (13, 4) == "tag." &&
|
if (var.first.substr (13, 4) == "tag." &&
|
||||||
(end = var->first.find (".coefficient")) != std::string::npos)
|
(end = var.first.find (".coefficient")) != std::string::npos)
|
||||||
{
|
{
|
||||||
std::string tag = var->first.substr (17, end - 17);
|
std::string tag = var.first.substr (17, end - 17);
|
||||||
|
|
||||||
if (hasTag (tag))
|
if (hasTag (tag))
|
||||||
value += var->second;
|
value += var.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
// urgency.user.keyword.<keyword>.coefficient
|
// urgency.user.keyword.<keyword>.coefficient
|
||||||
if (var->first.substr (13, 8) == "keyword." &&
|
if (var.first.substr (13, 8) == "keyword." &&
|
||||||
(end = var->first.find (".coefficient")) != std::string::npos)
|
(end = var.first.find (".coefficient")) != std::string::npos)
|
||||||
{
|
{
|
||||||
std::string keyword = var->first.substr (21, end - 21);
|
std::string keyword = var.first.substr (21, end - 21);
|
||||||
|
|
||||||
if (get ("description").find (keyword) != std::string::npos)
|
if (get ("description").find (keyword) != std::string::npos)
|
||||||
value += var->second;
|
value += var.second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (var->first.substr (0, 12) == "urgency.uda.")
|
else if (var.first.substr (0, 12) == "urgency.uda.")
|
||||||
{
|
{
|
||||||
// urgency.uda.<name>.coefficient
|
// urgency.uda.<name>.coefficient
|
||||||
// urgency.uda.<name>.<value>.coefficient
|
// urgency.uda.<name>.<value>.coefficient
|
||||||
std::string::size_type end = var->first.find (".coefficient");
|
std::string::size_type end = var.first.find (".coefficient");
|
||||||
if (end != std::string::npos)
|
if (end != std::string::npos)
|
||||||
{
|
{
|
||||||
const std::string uda = var->first.substr (12, end - 12);
|
const std::string uda = var.first.substr (12, end - 12);
|
||||||
std::string::size_type dot = uda.find (".");
|
std::string::size_type dot = uda.find (".");
|
||||||
if (dot == std::string::npos)
|
if (dot == std::string::npos)
|
||||||
{
|
{
|
||||||
// urgency.uda.<name>.coefficient
|
// urgency.uda.<name>.coefficient
|
||||||
if (has (uda))
|
if (has (uda))
|
||||||
value += var->second;
|
value += var.second;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// urgency.uda.<name>.<value>.coefficient
|
// urgency.uda.<name>.<value>.coefficient
|
||||||
if (get (uda.substr(0, dot)) == uda.substr(dot+1))
|
if (get (uda.substr(0, dot)) == uda.substr(dot+1))
|
||||||
value += var->second;
|
value += var.second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1744,20 +1717,19 @@ float Task::urgency_inherit () const
|
|||||||
dependencyGetBlocked (*this, blocked);
|
dependencyGetBlocked (*this, blocked);
|
||||||
|
|
||||||
float v = 0.0;
|
float v = 0.0;
|
||||||
std::vector <Task>::const_iterator it;
|
for (auto& task : blocked)
|
||||||
for (it = blocked.begin (); it != blocked.end (); ++it)
|
|
||||||
{
|
{
|
||||||
// urgency_blocked, _blocking, _project and _tags left out.
|
// urgency_blocked, _blocking, _project and _tags left out.
|
||||||
v += it->urgency_active ();
|
v += task.urgency_active ();
|
||||||
v += it->urgency_age ();
|
v += task.urgency_age ();
|
||||||
v += it->urgency_annotations ();
|
v += task.urgency_annotations ();
|
||||||
v += it->urgency_due ();
|
v += task.urgency_due ();
|
||||||
v += it->urgency_next ();
|
v += task.urgency_next ();
|
||||||
v += it->urgency_scheduled ();
|
v += task.urgency_scheduled ();
|
||||||
v += it->urgency_waiting ();
|
v += task.urgency_waiting ();
|
||||||
|
|
||||||
// Inherit from all parent tasks in the dependency chain recursively.
|
// Inherit from all parent tasks in the dependency chain recursively.
|
||||||
v += it->urgency_inherit ();
|
v += task.urgency_inherit ();
|
||||||
}
|
}
|
||||||
|
|
||||||
return v;
|
return v;
|
||||||
@@ -1910,17 +1882,16 @@ void Task::modify (modType type, bool text_required /* = false */)
|
|||||||
std::string label = " [1;37;43mMODIFICATION[0m ";
|
std::string label = " [1;37;43mMODIFICATION[0m ";
|
||||||
|
|
||||||
int modCount = 0;
|
int modCount = 0;
|
||||||
std::vector <A>::iterator a;
|
for (auto& a : context.cli._args)
|
||||||
for (a = context.cli._args.begin (); a != context.cli._args.end (); ++a)
|
|
||||||
{
|
{
|
||||||
if (a->hasTag ("MODIFICATION"))
|
if (a.hasTag ("MODIFICATION"))
|
||||||
{
|
{
|
||||||
if (a->hasTag ("ATTRIBUTE"))
|
if (a.hasTag ("ATTRIBUTE"))
|
||||||
{
|
{
|
||||||
// 'name' is canonical.
|
// 'name' is canonical.
|
||||||
// 'value' requires eval.
|
// 'value' requires eval.
|
||||||
std::string name = a->attribute ("name");
|
std::string name = a.attribute ("name");
|
||||||
std::string value = a->attribute ("value");
|
std::string value = a.attribute ("value");
|
||||||
if (value == "" ||
|
if (value == "" ||
|
||||||
value == "''" ||
|
value == "''" ||
|
||||||
value == "\"\"")
|
value == "\"\"")
|
||||||
@@ -1948,22 +1919,21 @@ void Task::modify (modType type, bool text_required /* = false */)
|
|||||||
split (deps, value, ',');
|
split (deps, value, ',');
|
||||||
|
|
||||||
// Apply or remove dendencies in turn.
|
// Apply or remove dendencies in turn.
|
||||||
std::vector <std::string>::iterator i;
|
for (auto& dep : deps)
|
||||||
for (i = deps.begin (); i != deps.end (); i++)
|
|
||||||
{
|
{
|
||||||
if ((*i)[0] == '-')
|
if (dep[0] == '-')
|
||||||
{
|
{
|
||||||
if ((*i).length () == 37)
|
if (dep.length () == 37)
|
||||||
removeDependency (context.tdb2.pending.id ((*i).substr (1)));
|
removeDependency (context.tdb2.pending.id (dep.substr (1)));
|
||||||
else
|
else
|
||||||
removeDependency (strtol ((*i).substr (1).c_str (), NULL, 10));
|
removeDependency (strtol (dep.substr (1).c_str (), NULL, 10));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((*i).length () == 36)
|
if (dep.length () == 36)
|
||||||
addDependency (context.tdb2.pending.id ((*i)));
|
addDependency (context.tdb2.pending.id (dep));
|
||||||
else
|
else
|
||||||
addDependency (strtol ((*i).c_str (), NULL, 10));
|
addDependency (strtol (dep.c_str (), NULL, 10));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2104,22 +2074,22 @@ void Task::modify (modType type, bool text_required /* = false */)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// arg7 from='from' global='1' raw='/from/to/g' to='to' ORIGINAL SUBSTITUTION MODIFICATION
|
// arg7 from='from' global='1' raw='/from/to/g' to='to' ORIGINAL SUBSTITUTION MODIFICATION
|
||||||
else if (a->hasTag ("SUBSTITUTION"))
|
else if (a.hasTag ("SUBSTITUTION"))
|
||||||
{
|
{
|
||||||
context.debug (label + "substitute " + a->attribute ("raw"));
|
context.debug (label + "substitute " + a.attribute ("raw"));
|
||||||
substitute (a->attribute ("from"),
|
substitute (a.attribute ("from"),
|
||||||
a->attribute ("to"),
|
a.attribute ("to"),
|
||||||
(a->attribute ("global") == "1"));
|
(a.attribute ("global") == "1"));
|
||||||
++modCount;
|
++modCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tags need special handling because they are essentially a vector stored
|
// Tags need special handling because they are essentially a vector stored
|
||||||
// in a single string, therefore Task::{add,remove}Tag must be called as
|
// in a single string, therefore Task::{add,remove}Tag must be called as
|
||||||
// appropriate.
|
// appropriate.
|
||||||
else if (a->hasTag ("TAG"))
|
else if (a.hasTag ("TAG"))
|
||||||
{
|
{
|
||||||
std::string tag = a->attribute ("name");
|
std::string tag = a.attribute ("name");
|
||||||
if (a->attribute ("sign") == "+")
|
if (a.attribute ("sign") == "+")
|
||||||
{
|
{
|
||||||
context.debug (label + "tags <-- add '" + tag + "'");
|
context.debug (label + "tags <-- add '" + tag + "'");
|
||||||
addTag (tag);
|
addTag (tag);
|
||||||
@@ -2135,12 +2105,12 @@ void Task::modify (modType type, bool text_required /* = false */)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// WORD and TERMINATED args are accumulated.
|
// WORD and TERMINATED args are accumulated.
|
||||||
else if (a->hasTag ("WORD") ||
|
else if (a.hasTag ("WORD") ||
|
||||||
a->hasTag ("TERMINATED"))
|
a.hasTag ("TERMINATED"))
|
||||||
{
|
{
|
||||||
if (text != "")
|
if (text != "")
|
||||||
text += ' ';
|
text += ' ';
|
||||||
text += a->attribute ("raw");
|
text += a.attribute ("raw");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unknown args are accumulated as though they were WORDs.
|
// Unknown args are accumulated as though they were WORDs.
|
||||||
@@ -2148,7 +2118,7 @@ void Task::modify (modType type, bool text_required /* = false */)
|
|||||||
{
|
{
|
||||||
if (text != "")
|
if (text != "")
|
||||||
text += ' ';
|
text += ' ';
|
||||||
text += a->attribute ("raw");
|
text += a.attribute ("raw");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1010,9 +1010,8 @@ bool Variant::operator_match (const Variant& other, const Task& task) const
|
|||||||
std::map <std::string, std::string> annotations;
|
std::map <std::string, std::string> annotations;
|
||||||
task.getAnnotations (annotations);
|
task.getAnnotations (annotations);
|
||||||
|
|
||||||
std::map <std::string, std::string>::iterator a;
|
for (auto& a : annotations)
|
||||||
for (a = annotations.begin (); a != annotations.end (); ++a)
|
if (r.match (a.second))
|
||||||
if (r.match (a->second))
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1028,9 +1027,8 @@ bool Variant::operator_match (const Variant& other, const Task& task) const
|
|||||||
std::map <std::string, std::string> annotations;
|
std::map <std::string, std::string> annotations;
|
||||||
task.getAnnotations (annotations);
|
task.getAnnotations (annotations);
|
||||||
|
|
||||||
std::map <std::string, std::string>::iterator a;
|
for (auto& a : annotations)
|
||||||
for (a = annotations.begin (); a != annotations.end (); ++a)
|
if (find (a.second, pattern, searchCaseSensitive) != std::string::npos)
|
||||||
if (find (a->second, pattern, searchCaseSensitive) != std::string::npos)
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,9 +60,8 @@ ViewTask::ViewTask ()
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
ViewTask::~ViewTask ()
|
ViewTask::~ViewTask ()
|
||||||
{
|
{
|
||||||
std::vector <Column*>::iterator i;
|
for (auto& col : _columns)
|
||||||
for (i = _columns.begin (); i != _columns.end (); ++i)
|
delete col;
|
||||||
delete *i;
|
|
||||||
|
|
||||||
_columns.clear ();
|
_columns.clear ();
|
||||||
}
|
}
|
||||||
@@ -297,7 +296,6 @@ std::string ViewTask::render (std::vector <Task>& data, std::vector <int>& seque
|
|||||||
// Compose, render columns, in sequence.
|
// Compose, render columns, in sequence.
|
||||||
_rows = 0;
|
_rows = 0;
|
||||||
std::vector <std::vector <std::string>> cells;
|
std::vector <std::vector <std::string>> cells;
|
||||||
std::vector <int>::iterator s;
|
|
||||||
for (unsigned int s = 0; s < sequence.size (); ++s)
|
for (unsigned int s = 0; s < sequence.size (); ++s)
|
||||||
{
|
{
|
||||||
max_lines = 0;
|
max_lines = 0;
|
||||||
@@ -334,10 +332,9 @@ std::string ViewTask::render (std::vector <Task>& data, std::vector <int>& seque
|
|||||||
if (s > 0 &&
|
if (s > 0 &&
|
||||||
_breaks.size () > 0)
|
_breaks.size () > 0)
|
||||||
{
|
{
|
||||||
std::vector <std::string>::iterator b;
|
for (auto& b : _breaks)
|
||||||
for (b = _breaks.begin (); b != _breaks.end (); ++b)
|
|
||||||
{
|
{
|
||||||
if (data[sequence[s - 1]].get (*b) != data[sequence[s]].get (*b))
|
if (data[sequence[s - 1]].get (b) != data[sequence[s]].get (b))
|
||||||
{
|
{
|
||||||
out += "\n";
|
out += "\n";
|
||||||
++_lines;
|
++_lines;
|
||||||
|
|||||||
@@ -56,9 +56,8 @@ ViewText::ViewText ()
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
ViewText::~ViewText ()
|
ViewText::~ViewText ()
|
||||||
{
|
{
|
||||||
std::vector <Column*>::iterator i;
|
for (auto& col : _columns)
|
||||||
for (i = _columns.begin (); i != _columns.end (); ++i)
|
delete col;
|
||||||
delete *i;
|
|
||||||
|
|
||||||
_columns.clear ();
|
_columns.clear ();
|
||||||
}
|
}
|
||||||
@@ -147,14 +146,13 @@ std::string ViewText::render ()
|
|||||||
|
|
||||||
// Sum the minimal widths.
|
// Sum the minimal widths.
|
||||||
int sum_minimal = 0;
|
int sum_minimal = 0;
|
||||||
std::vector <int>::iterator c;
|
for (auto& c : minimal)
|
||||||
for (c = minimal.begin (); c != minimal.end (); ++c)
|
sum_minimal += c;
|
||||||
sum_minimal += *c;
|
|
||||||
|
|
||||||
// Sum the ideal widths.
|
// Sum the ideal widths.
|
||||||
int sum_ideal = 0;
|
int sum_ideal = 0;
|
||||||
for (c = ideal.begin (); c != ideal.end (); ++c)
|
for (auto& c : ideal)
|
||||||
sum_ideal += *c;
|
sum_ideal += c;
|
||||||
|
|
||||||
// Calculate final column widths.
|
// Calculate final column widths.
|
||||||
int overage = _width
|
int overage = _width
|
||||||
|
|||||||
@@ -141,9 +141,8 @@ int main (int argc, char** argv)
|
|||||||
e.evaluatePostfixExpression (expression, result);
|
e.evaluatePostfixExpression (expression, result);
|
||||||
|
|
||||||
// Show any debug output.
|
// Show any debug output.
|
||||||
std::vector <std::string>::iterator i;
|
for (auto& i : context.debugMessages)
|
||||||
for (i = context.debugMessages.begin (); i != context.debugMessages.end (); ++i)
|
std::cout << i << "\n";
|
||||||
std::cout << *i << "\n";
|
|
||||||
|
|
||||||
// Show the result in string form.
|
// Show the result in string form.
|
||||||
std::cout << (std::string) result
|
std::cout << (std::string) result
|
||||||
|
|||||||
@@ -42,14 +42,13 @@ void dependencyGetBlocked (const Task& task, std::vector <Task>& blocked)
|
|||||||
{
|
{
|
||||||
std::string uuid = task.get ("uuid");
|
std::string uuid = task.get ("uuid");
|
||||||
|
|
||||||
const std::vector <Task>& all = context.tdb2.pending.get_tasks ();
|
auto all = context.tdb2.pending.get_tasks ();
|
||||||
std::vector <Task>::const_iterator it;
|
for (auto& it : all)
|
||||||
for (it = all.begin (); it != all.end (); ++it)
|
if ((it.getStatus () == Task::pending ||
|
||||||
if ((it->getStatus () == Task::pending ||
|
it.getStatus () == Task::waiting) &&
|
||||||
it->getStatus () == Task::waiting) &&
|
it.has ("depends") &&
|
||||||
it->has ("depends") &&
|
it.get ("depends").find (uuid) != std::string::npos)
|
||||||
it->get ("depends").find (uuid) != std::string::npos)
|
blocked.push_back (it);
|
||||||
blocked.push_back (*it);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -57,15 +56,11 @@ void dependencyGetBlocking (const Task& task, std::vector <Task>& blocking)
|
|||||||
{
|
{
|
||||||
std::string depends = task.get ("depends");
|
std::string depends = task.get ("depends");
|
||||||
if (depends != "")
|
if (depends != "")
|
||||||
{
|
for (auto& it : context.tdb2.pending.get_tasks ())
|
||||||
const std::vector <Task>& all = context.tdb2.pending.get_tasks ();
|
if ((it.getStatus () == Task::pending ||
|
||||||
std::vector <Task>::const_iterator it;
|
it.getStatus () == Task::waiting) &&
|
||||||
for (it = all.begin (); it != all.end (); ++it)
|
depends.find (it.get ("uuid")) != std::string::npos)
|
||||||
if ((it->getStatus () == Task::pending ||
|
blocking.push_back (it);
|
||||||
it->getStatus () == Task::waiting) &&
|
|
||||||
depends.find (it->get ("uuid")) != std::string::npos)
|
|
||||||
blocking.push_back (*it);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -152,9 +147,8 @@ void dependencyChainOnComplete (Task& task)
|
|||||||
std::cout << format (STRING_DEPEND_BLOCKED, task.id)
|
std::cout << format (STRING_DEPEND_BLOCKED, task.id)
|
||||||
<< "\n";
|
<< "\n";
|
||||||
|
|
||||||
std::vector <Task>::iterator b;
|
for (auto& b : blocking)
|
||||||
for (b = blocking.begin (); b != blocking.end (); ++b)
|
std::cout << " " << b.id << " " << b.get ("description") << "\n";
|
||||||
std::cout << " " << b->id << " " << b->get ("description") << "\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there are both blocking and blocked tasks, the chain is broken.
|
// If there are both blocking and blocked tasks, the chain is broken.
|
||||||
@@ -165,9 +159,8 @@ void dependencyChainOnComplete (Task& task)
|
|||||||
std::cout << STRING_DEPEND_BLOCKING
|
std::cout << STRING_DEPEND_BLOCKING
|
||||||
<< "\n";
|
<< "\n";
|
||||||
|
|
||||||
std::vector <Task>::iterator b;
|
for (auto& b : blocked)
|
||||||
for (b = blocked.begin (); b != blocked.end (); ++b)
|
std::cout << " " << b.id << " " << b.get ("description") << "\n";
|
||||||
std::cout << " " << b->id << " " << b->get ("description") << "\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!context.config.getBoolean ("dependency.confirmation") ||
|
if (!context.config.getBoolean ("dependency.confirmation") ||
|
||||||
@@ -175,22 +168,20 @@ void dependencyChainOnComplete (Task& task)
|
|||||||
{
|
{
|
||||||
// Repair the chain - everything in blocked should now depend on
|
// Repair the chain - everything in blocked should now depend on
|
||||||
// everything in blocking, instead of task.id.
|
// everything in blocking, instead of task.id.
|
||||||
std::vector <Task>::iterator left;
|
for (auto& left : blocked)
|
||||||
std::vector <Task>::iterator right;
|
|
||||||
for (left = blocked.begin (); left != blocked.end (); ++left)
|
|
||||||
{
|
{
|
||||||
left->removeDependency (task.id);
|
left.removeDependency (task.id);
|
||||||
|
|
||||||
for (right = blocking.begin (); right != blocking.end (); ++right)
|
for (auto& right : blocking)
|
||||||
left->addDependency (right->id);
|
left.addDependency (right.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now update TDB2, now that the updates have all occurred.
|
// Now update TDB2, now that the updates have all occurred.
|
||||||
for (left = blocked.begin (); left != blocked.end (); ++left)
|
for (auto& left : blocked)
|
||||||
context.tdb2.modify (*left);
|
context.tdb2.modify (left);
|
||||||
|
|
||||||
for (right = blocking.begin (); right != blocking.end (); ++right)
|
for (auto& right : blocking)
|
||||||
context.tdb2.modify (*right);
|
context.tdb2.modify (right);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -211,9 +202,8 @@ void dependencyChainOnStart (Task& task)
|
|||||||
std::cout << format (STRING_DEPEND_BLOCKED, task.id)
|
std::cout << format (STRING_DEPEND_BLOCKED, task.id)
|
||||||
<< "\n";
|
<< "\n";
|
||||||
|
|
||||||
std::vector <Task>::iterator b;
|
for (auto& b : blocking)
|
||||||
for (b = blocking.begin (); b != blocking.end (); ++b)
|
std::cout << " " << b.id << " " << b.get ("description") << "\n";
|
||||||
std::cout << " " << b->id << " " << b->get ("description") << "\n";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -254,11 +244,8 @@ void dependencyChainOnModify (Task& before, Task& after)
|
|||||||
std::vector <Task> blocked;
|
std::vector <Task> blocked;
|
||||||
dependencyGetBlocked (after, blocked);
|
dependencyGetBlocked (after, blocked);
|
||||||
|
|
||||||
std::vector <Task>::iterator b;
|
for (auto& b : blocked)
|
||||||
for (b = blocked.begin (); b != blocked.end (); ++b)
|
|
||||||
{
|
|
||||||
std::cout << "# dependencyChainOnModify\n";
|
std::cout << "# dependencyChainOnModify\n";
|
||||||
}
|
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|||||||
146
src/feedback.cpp
146
src/feedback.cpp
@@ -49,13 +49,12 @@ bool taskDiff (const Task& before, const Task& after)
|
|||||||
// Attributes are all there is, so figure the different attribute names
|
// Attributes are all there is, so figure the different attribute names
|
||||||
// between before and after.
|
// between before and after.
|
||||||
std::vector <std::string> beforeAtts;
|
std::vector <std::string> beforeAtts;
|
||||||
Task::const_iterator att;
|
for (auto& att : before)
|
||||||
for (att = before.begin (); att != before.end (); ++att)
|
beforeAtts.push_back (att.first);
|
||||||
beforeAtts.push_back (att->first);
|
|
||||||
|
|
||||||
std::vector <std::string> afterAtts;
|
std::vector <std::string> afterAtts;
|
||||||
for (att = after.begin (); att != after.end (); ++att)
|
for (auto& att : after)
|
||||||
afterAtts.push_back (att->first);
|
afterAtts.push_back (att.first);
|
||||||
|
|
||||||
std::vector <std::string> beforeOnly;
|
std::vector <std::string> beforeOnly;
|
||||||
std::vector <std::string> afterOnly;
|
std::vector <std::string> afterOnly;
|
||||||
@@ -65,10 +64,9 @@ bool taskDiff (const Task& before, const Task& after)
|
|||||||
afterOnly.size ())
|
afterOnly.size ())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
std::vector <std::string>::iterator name;
|
for (auto& name : beforeAtts)
|
||||||
for (name = beforeAtts.begin (); name != beforeAtts.end (); ++name)
|
if (name != "uuid" &&
|
||||||
if (*name != "uuid" &&
|
before.get (name) != after.get (name))
|
||||||
before.get (*name) != after.get (*name))
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -80,13 +78,12 @@ std::string taskDifferences (const Task& before, const Task& after)
|
|||||||
// Attributes are all there is, so figure the different attribute names
|
// Attributes are all there is, so figure the different attribute names
|
||||||
// between before and after.
|
// between before and after.
|
||||||
std::vector <std::string> beforeAtts;
|
std::vector <std::string> beforeAtts;
|
||||||
Task::const_iterator att;
|
for (auto& att : before)
|
||||||
for (att = before.begin (); att != before.end (); ++att)
|
beforeAtts.push_back (att.first);
|
||||||
beforeAtts.push_back (att->first);
|
|
||||||
|
|
||||||
std::vector <std::string> afterAtts;
|
std::vector <std::string> afterAtts;
|
||||||
for (att = after.begin (); att != after.end (); ++att)
|
for (auto& att : after)
|
||||||
afterAtts.push_back (att->first);
|
afterAtts.push_back (att.first);
|
||||||
|
|
||||||
std::vector <std::string> beforeOnly;
|
std::vector <std::string> beforeOnly;
|
||||||
std::vector <std::string> afterOnly;
|
std::vector <std::string> afterOnly;
|
||||||
@@ -94,15 +91,14 @@ std::string taskDifferences (const Task& before, const Task& after)
|
|||||||
|
|
||||||
// Now start generating a description of the differences.
|
// Now start generating a description of the differences.
|
||||||
std::stringstream out;
|
std::stringstream out;
|
||||||
std::vector <std::string>::iterator name;
|
for (auto& name : beforeOnly)
|
||||||
for (name = beforeOnly.begin (); name != beforeOnly.end (); ++name)
|
|
||||||
out << " - "
|
out << " - "
|
||||||
<< format (STRING_FEEDBACK_DELETED, ucFirst (*name))
|
<< format (STRING_FEEDBACK_DELETED, ucFirst (name))
|
||||||
<< "\n";
|
<< "\n";
|
||||||
|
|
||||||
for (name = afterOnly.begin (); name != afterOnly.end (); ++name)
|
for (auto& name : afterOnly)
|
||||||
{
|
{
|
||||||
if (*name == "depends")
|
if (name == "depends")
|
||||||
{
|
{
|
||||||
std::vector <int> deps_after;
|
std::vector <int> deps_after;
|
||||||
after.getDependencies (deps_after);
|
after.getDependencies (deps_after);
|
||||||
@@ -116,21 +112,21 @@ std::string taskDifferences (const Task& before, const Task& after)
|
|||||||
else
|
else
|
||||||
out << " - "
|
out << " - "
|
||||||
<< format (STRING_FEEDBACK_ATT_SET,
|
<< format (STRING_FEEDBACK_ATT_SET,
|
||||||
ucFirst (*name),
|
ucFirst (name),
|
||||||
renderAttribute (*name, after.get (*name)))
|
renderAttribute (name, after.get (name)))
|
||||||
<< "\n";
|
<< "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
for (name = beforeAtts.begin (); name != beforeAtts.end (); ++name)
|
for (auto& name : beforeAtts)
|
||||||
{
|
{
|
||||||
// Ignore UUID differences, and find values that changed, but are not also
|
// Ignore UUID differences, and find values that changed, but are not also
|
||||||
// in the beforeOnly and afterOnly lists, which have been handled above..
|
// in the beforeOnly and afterOnly lists, which have been handled above..
|
||||||
if (*name != "uuid" &&
|
if (name != "uuid" &&
|
||||||
before.get (*name) != after.get (*name) &&
|
before.get (name) != after.get (name) &&
|
||||||
std::find (beforeOnly.begin (), beforeOnly.end (), *name) == beforeOnly.end () &&
|
std::find (beforeOnly.begin (), beforeOnly.end (), name) == beforeOnly.end () &&
|
||||||
std::find (afterOnly.begin (), afterOnly.end (), *name) == afterOnly.end ())
|
std::find (afterOnly.begin (), afterOnly.end (), name) == afterOnly.end ())
|
||||||
{
|
{
|
||||||
if (*name == "depends")
|
if (name == "depends")
|
||||||
{
|
{
|
||||||
std::vector <int> deps_before;
|
std::vector <int> deps_before;
|
||||||
before.getDependencies (deps_before);
|
before.getDependencies (deps_before);
|
||||||
@@ -149,9 +145,9 @@ std::string taskDifferences (const Task& before, const Task& after)
|
|||||||
else
|
else
|
||||||
out << " - "
|
out << " - "
|
||||||
<< format (STRING_FEEDBACK_ATT_MOD,
|
<< format (STRING_FEEDBACK_ATT_MOD,
|
||||||
ucFirst (*name),
|
ucFirst (name),
|
||||||
renderAttribute (*name, before.get (*name)),
|
renderAttribute (name, before.get (name)),
|
||||||
renderAttribute (*name, after.get (*name)))
|
renderAttribute (name, after.get (name)))
|
||||||
<< "\n";
|
<< "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -176,13 +172,12 @@ std::string taskInfoDifferences (
|
|||||||
// Attributes are all there is, so figure the different attribute names
|
// Attributes are all there is, so figure the different attribute names
|
||||||
// between before and after.
|
// between before and after.
|
||||||
std::vector <std::string> beforeAtts;
|
std::vector <std::string> beforeAtts;
|
||||||
Task::const_iterator att;
|
for (auto& att : before)
|
||||||
for (att = before.begin (); att != before.end (); ++att)
|
beforeAtts.push_back (att.first);
|
||||||
beforeAtts.push_back (att->first);
|
|
||||||
|
|
||||||
std::vector <std::string> afterAtts;
|
std::vector <std::string> afterAtts;
|
||||||
for (att = after.begin (); att != after.end (); ++att)
|
for (auto& att : after)
|
||||||
afterAtts.push_back (att->first);
|
afterAtts.push_back (att.first);
|
||||||
|
|
||||||
std::vector <std::string> beforeOnly;
|
std::vector <std::string> beforeOnly;
|
||||||
std::vector <std::string> afterOnly;
|
std::vector <std::string> afterOnly;
|
||||||
@@ -190,10 +185,9 @@ std::string taskInfoDifferences (
|
|||||||
|
|
||||||
// Now start generating a description of the differences.
|
// Now start generating a description of the differences.
|
||||||
std::stringstream out;
|
std::stringstream out;
|
||||||
std::vector <std::string>::iterator name;
|
for (auto& name : beforeOnly)
|
||||||
for (name = beforeOnly.begin (); name != beforeOnly.end (); ++name)
|
|
||||||
{
|
{
|
||||||
if (*name == "depends")
|
if (name == "depends")
|
||||||
{
|
{
|
||||||
std::vector <int> deps_before;
|
std::vector <int> deps_before;
|
||||||
before.getDependencies (deps_before);
|
before.getDependencies (deps_before);
|
||||||
@@ -203,27 +197,27 @@ std::string taskInfoDifferences (
|
|||||||
out << format (STRING_FEEDBACK_DEP_DEL, from)
|
out << format (STRING_FEEDBACK_DEP_DEL, from)
|
||||||
<< "\n";
|
<< "\n";
|
||||||
}
|
}
|
||||||
else if (name->substr (0, 11) == "annotation_")
|
else if (name.substr (0, 11) == "annotation_")
|
||||||
{
|
{
|
||||||
out << format (STRING_FEEDBACK_ANN_DEL, before.get (*name))
|
out << format (STRING_FEEDBACK_ANN_DEL, before.get (name))
|
||||||
<< "\n";
|
<< "\n";
|
||||||
}
|
}
|
||||||
else if (*name == "start")
|
else if (name == "start")
|
||||||
{
|
{
|
||||||
out << format (STRING_FEEDBACK_ATT_DEL_DUR, ucFirst (*name),
|
out << format (STRING_FEEDBACK_ATT_DEL_DUR, ucFirst (name),
|
||||||
Duration (current_timestamp - last_timestamp).formatPrecise ())
|
Duration (current_timestamp - last_timestamp).formatPrecise ())
|
||||||
<< "\n";
|
<< "\n";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
out << format (STRING_FEEDBACK_ATT_DEL, ucFirst (*name))
|
out << format (STRING_FEEDBACK_ATT_DEL, ucFirst (name))
|
||||||
<< "\n";
|
<< "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (name = afterOnly.begin (); name != afterOnly.end (); ++name)
|
for (auto& name : afterOnly)
|
||||||
{
|
{
|
||||||
if (*name == "depends")
|
if (name == "depends")
|
||||||
{
|
{
|
||||||
std::vector <int> deps_after;
|
std::vector <int> deps_after;
|
||||||
after.getDependencies (deps_after);
|
after.getDependencies (deps_after);
|
||||||
@@ -233,30 +227,31 @@ std::string taskInfoDifferences (
|
|||||||
out << format (STRING_FEEDBACK_DEP_WAS_SET, to)
|
out << format (STRING_FEEDBACK_DEP_WAS_SET, to)
|
||||||
<< "\n";
|
<< "\n";
|
||||||
}
|
}
|
||||||
else if (name->substr (0, 11) == "annotation_")
|
else if (name.substr (0, 11) == "annotation_")
|
||||||
{
|
{
|
||||||
out << format (STRING_FEEDBACK_ANN_ADD, after.get (*name))
|
out << format (STRING_FEEDBACK_ANN_ADD, after.get (name))
|
||||||
<< "\n";
|
<< "\n";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (*name == "start")
|
if (name == "start")
|
||||||
last_timestamp = current_timestamp;
|
last_timestamp = current_timestamp;
|
||||||
|
|
||||||
out << format (STRING_FEEDBACK_ATT_WAS_SET,
|
out << format (STRING_FEEDBACK_ATT_WAS_SET,
|
||||||
ucFirst (*name),
|
ucFirst (name),
|
||||||
renderAttribute (*name, after.get (*name), dateformat))
|
renderAttribute (name, after.get (name), dateformat))
|
||||||
<< "\n";
|
<< "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (name = beforeAtts.begin (); name != beforeAtts.end (); ++name)
|
for (auto& name : beforeAtts)
|
||||||
if (*name != "uuid" &&
|
if (name != "uuid" &&
|
||||||
*name != "modified" &&
|
name != "modified" &&
|
||||||
before.get (*name) != after.get (*name) &&
|
before.get (name) != after.get (name) &&
|
||||||
before.get (*name) != "" && after.get (*name) != "")
|
before.get (name) != "" &&
|
||||||
|
after.get (name) != "")
|
||||||
{
|
{
|
||||||
if (*name == "depends")
|
if (name == "depends")
|
||||||
{
|
{
|
||||||
std::vector <int> deps_before;
|
std::vector <int> deps_before;
|
||||||
before.getDependencies (deps_before);
|
before.getDependencies (deps_before);
|
||||||
@@ -271,16 +266,16 @@ std::string taskInfoDifferences (
|
|||||||
out << format (STRING_FEEDBACK_DEP_WAS_MOD, from, to)
|
out << format (STRING_FEEDBACK_DEP_WAS_MOD, from, to)
|
||||||
<< "\n";
|
<< "\n";
|
||||||
}
|
}
|
||||||
else if (name->substr (0, 11) == "annotation_")
|
else if (name.substr (0, 11) == "annotation_")
|
||||||
{
|
{
|
||||||
out << format (STRING_FEEDBACK_ANN_WAS_MOD, after.get (*name))
|
out << format (STRING_FEEDBACK_ANN_WAS_MOD, after.get (name))
|
||||||
<< "\n";
|
<< "\n";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
out << format (STRING_FEEDBACK_ATT_WAS_MOD,
|
out << format (STRING_FEEDBACK_ATT_WAS_MOD,
|
||||||
ucFirst (*name),
|
ucFirst (name),
|
||||||
renderAttribute (*name, before.get (*name), dateformat),
|
renderAttribute (name, before.get (name), dateformat),
|
||||||
renderAttribute (*name, after.get (*name), dateformat))
|
renderAttribute (name, after.get (name), dateformat))
|
||||||
<< "\n";
|
<< "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -397,24 +392,23 @@ void feedback_unblocked (const Task& task)
|
|||||||
dependencyGetBlocked (task, blocked);
|
dependencyGetBlocked (task, blocked);
|
||||||
|
|
||||||
// Scan all the tasks that were blocked by this task
|
// Scan all the tasks that were blocked by this task
|
||||||
std::vector <Task>::iterator i;
|
for (auto& i : blocked)
|
||||||
for (i = blocked.begin (); i != blocked.end (); ++i)
|
|
||||||
{
|
{
|
||||||
std::vector <Task> blocking;
|
std::vector <Task> blocking;
|
||||||
dependencyGetBlocking (*i, blocking);
|
dependencyGetBlocking (i, blocking);
|
||||||
if (blocking.size () == 0)
|
if (blocking.size () == 0)
|
||||||
{
|
{
|
||||||
if (i->id)
|
if (i.id)
|
||||||
std::cout << format (STRING_FEEDBACK_UNBLOCKED,
|
std::cout << format (STRING_FEEDBACK_UNBLOCKED,
|
||||||
i->id,
|
i.id,
|
||||||
i->get ("description"))
|
i.get ("description"))
|
||||||
<< "\n";
|
<< "\n";
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::string uuid = i->get ("uuid");
|
std::string uuid = i.get ("uuid");
|
||||||
std::cout << format (STRING_FEEDBACK_UNBLOCKED,
|
std::cout << format (STRING_FEEDBACK_UNBLOCKED,
|
||||||
i->get ("uuid"),
|
i.get ("uuid"),
|
||||||
i->get ("description"))
|
i.get ("description"))
|
||||||
<< "\n";
|
<< "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -429,10 +423,9 @@ void feedback_backlog ()
|
|||||||
context.verbose ("sync"))
|
context.verbose ("sync"))
|
||||||
{
|
{
|
||||||
std::vector <std::string> lines = context.tdb2.backlog.get_lines ();
|
std::vector <std::string> lines = context.tdb2.backlog.get_lines ();
|
||||||
std::vector <std::string>::iterator line;
|
for (auto& line : lines)
|
||||||
for (line = lines.begin (); line != lines.end (); ++line)
|
|
||||||
{
|
{
|
||||||
if ((*line)[0] == '{')
|
if ((line)[0] == '{')
|
||||||
{
|
{
|
||||||
context.footnote (STRING_FEEDBACK_BACKLOG);
|
context.footnote (STRING_FEEDBACK_BACKLOG);
|
||||||
break;
|
break;
|
||||||
@@ -518,12 +511,11 @@ static void countTasks (
|
|||||||
int& count_pending,
|
int& count_pending,
|
||||||
int& count_done)
|
int& count_done)
|
||||||
{
|
{
|
||||||
std::vector <Task>::const_iterator it;
|
for (auto& it : all)
|
||||||
for (it = all.begin (); it != all.end (); ++it)
|
|
||||||
{
|
{
|
||||||
if (it->get ("project") == project)
|
if (it.get ("project") == project)
|
||||||
{
|
{
|
||||||
switch (it->getStatus ())
|
switch (it.getStatus ())
|
||||||
{
|
{
|
||||||
case Task::pending:
|
case Task::pending:
|
||||||
case Task::waiting:
|
case Task::waiting:
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ void legacyColumnMap (std::string& name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If a legacy column was used, complain about it, but modify it anyway.
|
// If a legacy column was used, complain about it, but modify it anyway.
|
||||||
std::map <std::string, std::string>::iterator found = legacyMap.find (name);
|
auto found = legacyMap.find (name);
|
||||||
if (found != legacyMap.end ())
|
if (found != legacyMap.end ())
|
||||||
{
|
{
|
||||||
context.footnote (format (STRING_LEGACY_PRIORITY, name, found->second));
|
context.footnote (format (STRING_LEGACY_PRIORITY, name, found->second));
|
||||||
@@ -95,7 +95,7 @@ void legacySortColumnMap (std::string& name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If a legacy column was used, complain about it, but modify it anyway.
|
// If a legacy column was used, complain about it, but modify it anyway.
|
||||||
std::map <std::string, std::string>::iterator found = legacyMap.find (name);
|
auto found = legacyMap.find (name);
|
||||||
if (found != legacyMap.end ())
|
if (found != legacyMap.end ())
|
||||||
{
|
{
|
||||||
context.footnote (format (STRING_LEGACY_PRIORITY, name, found->second));
|
context.footnote (format (STRING_LEGACY_PRIORITY, name, found->second));
|
||||||
@@ -115,25 +115,24 @@ std::string legacyCheckForDeprecatedColor ()
|
|||||||
std::string legacyCheckForDeprecatedVariables ()
|
std::string legacyCheckForDeprecatedVariables ()
|
||||||
{
|
{
|
||||||
std::vector <std::string> deprecated;
|
std::vector <std::string> deprecated;
|
||||||
std::map <std::string, std::string>::const_iterator it;
|
for (auto& it : context.config)
|
||||||
for (it = context.config.begin (); it != context.config.end (); ++it)
|
|
||||||
{
|
{
|
||||||
// 2014-07-04: report.*.limit removed.
|
// 2014-07-04: report.*.limit removed.
|
||||||
|
|
||||||
// report.*.annotations
|
// report.*.annotations
|
||||||
if (it->first.length () > 19 &&
|
if (it.first.length () > 19 &&
|
||||||
it->first.substr (0, 7) == "report." &&
|
it.first.substr (0, 7) == "report." &&
|
||||||
it->first.substr (it->first.length () - 12) == ".annotations")
|
it.first.substr (it.first.length () - 12) == ".annotations")
|
||||||
deprecated.push_back (it->first);
|
deprecated.push_back (it.first);
|
||||||
|
|
||||||
if (it->first == "next" ||
|
if (it.first == "next" ||
|
||||||
it->first == "annotations" ||
|
it.first == "annotations" ||
|
||||||
it->first == "export.ical.class")
|
it.first == "export.ical.class")
|
||||||
deprecated.push_back (it->first);
|
deprecated.push_back (it.first);
|
||||||
|
|
||||||
// Deprecated іn 2.4.0.
|
// Deprecated іn 2.4.0.
|
||||||
if (it->first == "alias._query")
|
if (it.first == "alias._query")
|
||||||
deprecated.push_back (it->first);
|
deprecated.push_back (it.first);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::stringstream out;
|
std::stringstream out;
|
||||||
@@ -142,9 +141,8 @@ std::string legacyCheckForDeprecatedVariables ()
|
|||||||
out << STRING_CONFIG_DEPRECATED_VAR
|
out << STRING_CONFIG_DEPRECATED_VAR
|
||||||
<< "\n";
|
<< "\n";
|
||||||
|
|
||||||
std::vector <std::string>::iterator it2;
|
for (auto& dep : deprecated)
|
||||||
for (it2 = deprecated.begin (); it2 != deprecated.end (); ++it2)
|
out << " " << dep << "\n";
|
||||||
out << " " << *it2 << "\n";
|
|
||||||
|
|
||||||
out << "\n";
|
out << "\n";
|
||||||
}
|
}
|
||||||
@@ -156,16 +154,15 @@ std::string legacyCheckForDeprecatedVariables ()
|
|||||||
std::string legacyCheckForDeprecatedColumns ()
|
std::string legacyCheckForDeprecatedColumns ()
|
||||||
{
|
{
|
||||||
std::vector <std::string> deprecated;
|
std::vector <std::string> deprecated;
|
||||||
std::map <std::string, std::string>::const_iterator it;
|
for (auto& it : context.config)
|
||||||
for (it = context.config.begin (); it != context.config.end (); ++it)
|
|
||||||
{
|
{
|
||||||
if (it->first.find ("report") == 0)
|
if (it.first.find ("report") == 0)
|
||||||
{
|
{
|
||||||
std::string value = context.config.get (it->first);
|
std::string value = context.config.get (it.first);
|
||||||
if (value.find ("entry_time") != std::string::npos ||
|
if (value.find ("entry_time") != std::string::npos ||
|
||||||
value.find ("start_time") != std::string::npos ||
|
value.find ("start_time") != std::string::npos ||
|
||||||
value.find ("end_time") != std::string::npos)
|
value.find ("end_time") != std::string::npos)
|
||||||
deprecated.push_back (it->first);
|
deprecated.push_back (it.first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,9 +174,8 @@ std::string legacyCheckForDeprecatedColumns ()
|
|||||||
out << STRING_CONFIG_DEPRECATED_COL
|
out << STRING_CONFIG_DEPRECATED_COL
|
||||||
<< "\n";
|
<< "\n";
|
||||||
|
|
||||||
std::vector <std::string>::iterator it2;
|
for (auto& dep : deprecated)
|
||||||
for (it2 = deprecated.begin (); it2 != deprecated.end (); ++it2)
|
out << " " << dep << "=" << context.config.get (dep) << "\n";
|
||||||
out << " " << *it2 << "=" << context.config.get (*it2) << "\n";
|
|
||||||
|
|
||||||
out << "\n";
|
out << "\n";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,56 +60,54 @@ void handleRecurrence ()
|
|||||||
if (! context.config.getBoolean ("recurrence"))
|
if (! context.config.getBoolean ("recurrence"))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
std::vector <Task> tasks = context.tdb2.pending.get_tasks ();
|
auto tasks = context.tdb2.pending.get_tasks ();
|
||||||
Date now;
|
Date now;
|
||||||
|
|
||||||
// Look at all tasks and find any recurring ones.
|
// Look at all tasks and find any recurring ones.
|
||||||
std::vector <Task>::iterator t;
|
for (auto& t : tasks)
|
||||||
for (t = tasks.begin (); t != tasks.end (); ++t)
|
|
||||||
{
|
{
|
||||||
if (t->getStatus () == Task::recurring)
|
if (t.getStatus () == Task::recurring)
|
||||||
{
|
{
|
||||||
// Generate a list of due dates for this recurring task, regardless of
|
// Generate a list of due dates for this recurring task, regardless of
|
||||||
// the mask.
|
// the mask.
|
||||||
std::vector <Date> due;
|
std::vector <Date> due;
|
||||||
if (!generateDueDates (*t, due))
|
if (!generateDueDates (t, due))
|
||||||
{
|
{
|
||||||
// Determine the end date.
|
// Determine the end date.
|
||||||
t->setStatus (Task::deleted);
|
t.setStatus (Task::deleted);
|
||||||
context.tdb2.modify (*t);
|
context.tdb2.modify (t);
|
||||||
context.footnote (onExpiration (*t));
|
context.footnote (onExpiration (t));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the mask from the parent task.
|
// Get the mask from the parent task.
|
||||||
std::string mask = t->get ("mask");
|
std::string mask = t.get ("mask");
|
||||||
|
|
||||||
// Iterate over the due dates, and check each against the mask.
|
// Iterate over the due dates, and check each against the mask.
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
std::vector <Date>::iterator d;
|
for (auto& d : due)
|
||||||
for (d = due.begin (); d != due.end (); ++d)
|
|
||||||
{
|
{
|
||||||
if (mask.length () <= i)
|
if (mask.length () <= i)
|
||||||
{
|
{
|
||||||
changed = true;
|
changed = true;
|
||||||
|
|
||||||
Task rec (*t); // Clone the parent.
|
Task rec (t); // Clone the parent.
|
||||||
rec.setStatus (Task::pending); // Change the status.
|
rec.setStatus (Task::pending); // Change the status.
|
||||||
rec.id = context.tdb2.next_id (); // New ID.
|
rec.id = context.tdb2.next_id (); // New ID.
|
||||||
rec.set ("uuid", uuid ()); // New UUID.
|
rec.set ("uuid", uuid ()); // New UUID.
|
||||||
rec.set ("parent", t->get ("uuid")); // Remember mom.
|
rec.set ("parent", t.get ("uuid")); // Remember mom.
|
||||||
rec.setAsNow ("entry"); // New entry date.
|
rec.setAsNow ("entry"); // New entry date.
|
||||||
|
|
||||||
char dueDate[16];
|
char dueDate[16];
|
||||||
sprintf (dueDate, "%u", (unsigned int) d->toEpoch ());
|
sprintf (dueDate, "%u", (unsigned int) d.toEpoch ());
|
||||||
rec.set ("due", dueDate); // Store generated due date.
|
rec.set ("due", dueDate); // Store generated due date.
|
||||||
|
|
||||||
if (t->has ("wait"))
|
if (t.has ("wait"))
|
||||||
{
|
{
|
||||||
Date old_wait (t->get_date ("wait"));
|
Date old_wait (t.get_date ("wait"));
|
||||||
Date old_due (t->get_date ("due"));
|
Date old_due (t.get_date ("due"));
|
||||||
Date due (*d);
|
Date due (d);
|
||||||
sprintf (dueDate, "%u", (unsigned int) (due + (old_wait - old_due)).toEpoch ());
|
sprintf (dueDate, "%u", (unsigned int) (due + (old_wait - old_due)).toEpoch ());
|
||||||
rec.set ("wait", dueDate);
|
rec.set ("wait", dueDate);
|
||||||
rec.setStatus (Task::waiting);
|
rec.setStatus (Task::waiting);
|
||||||
@@ -137,20 +135,20 @@ void handleRecurrence ()
|
|||||||
// Only modify the parent if necessary.
|
// Only modify the parent if necessary.
|
||||||
if (changed)
|
if (changed)
|
||||||
{
|
{
|
||||||
t->set ("mask", mask);
|
t.set ("mask", mask);
|
||||||
context.tdb2.modify (*t);
|
context.tdb2.modify (t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Non-recurring tasks expire too.
|
// Non-recurring tasks expire too.
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (t->has ("until") &&
|
if (t.has ("until") &&
|
||||||
Date (t->get_date ("until")) < now)
|
Date (t.get_date ("until")) < now)
|
||||||
{
|
{
|
||||||
t->setStatus (Task::deleted);
|
t.setStatus (Task::deleted);
|
||||||
context.tdb2.modify(*t);
|
context.tdb2.modify(t);
|
||||||
context.footnote (onExpiration (*t));
|
context.footnote (onExpiration (t));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -424,14 +422,11 @@ bool nag (Task& task)
|
|||||||
std::string nagMessage = context.config.get ("nag");
|
std::string nagMessage = context.config.get ("nag");
|
||||||
if (nagMessage != "")
|
if (nagMessage != "")
|
||||||
{
|
{
|
||||||
// Load all pending tasks.
|
|
||||||
std::vector <Task> tasks = context.tdb2.pending.get_tasks ();
|
|
||||||
|
|
||||||
// Scan all pending tasks.
|
// Scan all pending tasks.
|
||||||
std::vector <Task>::iterator t;
|
auto pending = context.tdb2.pending.get_tasks ();
|
||||||
for (t = tasks.begin (); t != tasks.end (); ++t)
|
for (auto& t : pending)
|
||||||
{
|
{
|
||||||
if (t->urgency () > task.urgency ())
|
if (t.urgency () > task.urgency ())
|
||||||
{
|
{
|
||||||
context.footnote (nagMessage);
|
context.footnote (nagMessage);
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -53,15 +53,14 @@ void initializeColorRules ()
|
|||||||
// Load all the configuration values, filter to only the ones that begin with
|
// Load all the configuration values, filter to only the ones that begin with
|
||||||
// "color.", then store name/value in gsColor, and name in rules.
|
// "color.", then store name/value in gsColor, and name in rules.
|
||||||
std::vector <std::string> rules;
|
std::vector <std::string> rules;
|
||||||
Config::const_iterator v;
|
for (auto& v : context.config)
|
||||||
for (v = context.config.begin (); v != context.config.end (); ++v)
|
|
||||||
{
|
{
|
||||||
if (v->first.substr (0, 6) == "color.")
|
if (v.first.substr (0, 6) == "color.")
|
||||||
{
|
{
|
||||||
Color c (v->second);
|
Color c (v.second);
|
||||||
gsColor[v->first] = c;
|
gsColor[v.first] = c;
|
||||||
|
|
||||||
rules.push_back (v->first);
|
rules.push_back (v.first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,16 +70,14 @@ void initializeColorRules ()
|
|||||||
std::vector <std::string> precedence;
|
std::vector <std::string> precedence;
|
||||||
split (precedence, context.config.get ("rule.precedence.color"), ',');
|
split (precedence, context.config.get ("rule.precedence.color"), ',');
|
||||||
|
|
||||||
std::vector <std::string>::iterator p;
|
for (auto& p : precedence)
|
||||||
for (p = precedence.begin (); p != precedence.end (); ++p)
|
|
||||||
{
|
{
|
||||||
// Add the leading "color." string.
|
// Add the leading "color." string.
|
||||||
std::string rule = "color." + *p;
|
std::string rule = "color." + p;
|
||||||
autoComplete (rule, rules, results, 3); // Hard-coded 3.
|
autoComplete (rule, rules, results, 3); // Hard-coded 3.
|
||||||
|
|
||||||
std::vector <std::string>::iterator r;
|
for (auto& r : results)
|
||||||
for (r = results.begin (); r != results.end (); ++r)
|
gsPrecedence.push_back (r);
|
||||||
gsPrecedence.push_back (*r);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,11 +182,10 @@ static void colorizeKeyword (Task& task, const std::string& rule, const Color& b
|
|||||||
// first match.
|
// first match.
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Task::iterator it;
|
for (auto& it : task)
|
||||||
for (it = task.begin (); it != task.end (); ++it)
|
|
||||||
{
|
{
|
||||||
if (it->first.substr (0, 11) == "annotation_" &&
|
if (it.first.substr (0, 11) == "annotation_" &&
|
||||||
find (it->second, rule.substr (14), sensitive) != std::string::npos)
|
find (it.second, rule.substr (14), sensitive) != std::string::npos)
|
||||||
{
|
{
|
||||||
c.blend (base);
|
c.blend (base);
|
||||||
return;
|
return;
|
||||||
@@ -292,8 +288,7 @@ void autoColorize (Task& task, Color& c)
|
|||||||
// Note: c already contains colors specifically assigned via command.
|
// Note: c already contains colors specifically assigned via command.
|
||||||
// Note: These rules form a hierarchy - the last rule is King, hence the
|
// Note: These rules form a hierarchy - the last rule is King, hence the
|
||||||
// reverse iterator.
|
// reverse iterator.
|
||||||
std::vector <std::string>::reverse_iterator r;
|
for (auto r = gsPrecedence.rbegin (); r != gsPrecedence.rend (); ++r)
|
||||||
for (r = gsPrecedence.rbegin (); r != gsPrecedence.rend (); ++r)
|
|
||||||
{
|
{
|
||||||
Color base = gsColor[*r];
|
Color base = gsColor[*r];
|
||||||
if (base.nontrivial ())
|
if (base.nontrivial ())
|
||||||
|
|||||||
@@ -80,10 +80,9 @@ static bool sort_compare (int left, int right)
|
|||||||
float left_real;
|
float left_real;
|
||||||
float right_real;
|
float right_real;
|
||||||
|
|
||||||
std::vector <std::string>::iterator k;
|
for (auto& k : global_keys)
|
||||||
for (k = global_keys.begin (); k != global_keys.end (); ++k)
|
|
||||||
{
|
{
|
||||||
context.decomposeSortField (*k, field, ascending, breakIndicator);
|
context.decomposeSortField (k, field, ascending, breakIndicator);
|
||||||
|
|
||||||
// Urgency.
|
// Urgency.
|
||||||
if (field == "urgency")
|
if (field == "urgency")
|
||||||
|
|||||||
13
src/util.cpp
13
src/util.cpp
@@ -156,23 +156,22 @@ int autoComplete (
|
|||||||
unsigned int length = partial.length ();
|
unsigned int length = partial.length ();
|
||||||
if (length)
|
if (length)
|
||||||
{
|
{
|
||||||
std::vector <std::string>::const_iterator item;
|
for (auto& item : list)
|
||||||
for (item = list.begin (); item != list.end (); ++item)
|
|
||||||
{
|
{
|
||||||
// An exact match is a special case. Assume there is only one exact match
|
// An exact match is a special case. Assume there is only one exact match
|
||||||
// and return immediately.
|
// and return immediately.
|
||||||
if (partial == *item)
|
if (partial == item)
|
||||||
{
|
{
|
||||||
matches.clear ();
|
matches.clear ();
|
||||||
matches.push_back (*item);
|
matches.push_back (item);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Maintain a list of partial matches.
|
// Maintain a list of partial matches.
|
||||||
else if (length >= (unsigned) minimum &&
|
else if (length >= (unsigned) minimum &&
|
||||||
length <= item->length () &&
|
length <= item.length () &&
|
||||||
partial == item->substr (0, length))
|
partial == item.substr (0, length))
|
||||||
matches.push_back (*item);
|
matches.push_back (item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user