Portability: Updated to make main re-entrant()

- New INSTALL instructions to emscripten, and AUTHORS for contribution.
This commit is contained in:
Mark Scannell 2018-01-31 19:45:07 -05:00 committed by Paul Beckingham
parent cae3f06b7d
commit 7af6db4c17
112 changed files with 960 additions and 1147 deletions

View file

@ -60,7 +60,6 @@
#define APPROACHING_INFINITY 1000 // Close enough. This isn't rocket surgery.
extern Context context;
extern Task& contextTask;
static const float epsilon = 0.000001;
@ -336,7 +335,7 @@ Task::dateState Task::getDateState (const std::string& name) const
return dateLaterToday;
}
int imminentperiod = context.config.getInteger ("due");
int imminentperiod = Context::getContext ().config.getInteger ("due");
if (imminentperiod == 0)
return dateAfterToday;
@ -519,7 +518,7 @@ bool Task::is_dueyear () const
////////////////////////////////////////////////////////////////////////////////
bool Task::is_udaPresent () const
{
for (auto& col : context.columns)
for (auto& col : Context::getContext ().columns)
if (col.second->is_uda () &&
has (col.first))
return true;
@ -532,7 +531,7 @@ bool Task::is_orphanPresent () const
{
for (auto& att : data)
if (att.first.compare (0, 11, "annotation_", 11) != 0)
if (context.columns.find (att.first) == context.columns.end ())
if (Context::getContext ().columns.find (att.first) == Context::getContext ().columns.end ())
return true;
return false;
@ -783,7 +782,7 @@ void Task::parseJSON (const json::object* root_obj)
<< "' with value '"
<< i.second
<< "' --> preserved\n";
context.debug (message.str ());
Context::getContext ().debug (message.str ());
#endif
auto text = i.second->dump ();
Lexer::dequote (text);
@ -818,7 +817,7 @@ void Task::parseLegacy (const std::string& line)
message << "Invalid fileformat at line '"
<< line
<< '\'';
context.debug (message.str ());
Context::getContext ().debug (message.str ());
#endif
throw std::string ("Unrecognized Taskwarrior file format or blank line in data.");
break;
@ -962,7 +961,7 @@ std::string Task::composeJSON (bool decorate /*= false*/) const
// and Taskserver 1.2.0 is released, the default for
// 'json.depends.array' can revert to 'on'.
&& context.config.getBoolean ("json.depends.array")
&& Context::getContext ().config.getBoolean ("json.depends.array")
#endif
)
{
@ -1124,14 +1123,14 @@ void Task::setAnnotations (const std::map <std::string, std::string>& annotation
void Task::addDependency (int depid)
{
// Check that id is resolvable.
std::string uuid = context.tdb2.pending.uuid (depid);
std::string uuid = Context::getContext ().tdb2.pending.uuid (depid);
if (uuid == "")
throw format ("Could not create a dependency on task {1} - not found.", depid);
std::string depends = get ("depends");
if (depends.find (uuid) != std::string::npos)
{
context.footnote (format ("Task {1} already depends on task {2}.", id, depid));
Context::getContext ().footnote (format ("Task {1} already depends on task {2}.", id, depid));
return;
}
@ -1155,7 +1154,7 @@ void Task::addDependency (const std::string& uuid)
else
{
#ifdef PRODUCT_TASKWARRIOR
context.footnote (format ("Task {1} already depends on task {2}.", get ("uuid"), uuid));
Context::getContext ().footnote (format ("Task {1} already depends on task {2}.", get ("uuid"), uuid));
#endif
return;
}
@ -1193,7 +1192,7 @@ void Task::removeDependency (const std::string& uuid)
void Task::removeDependency (int id)
{
std::string depends = get ("depends");
std::string uuid = context.tdb2.pending.uuid (id);
std::string uuid = Context::getContext ().tdb2.pending.uuid (id);
if (uuid != "" && depends.find (uuid) != std::string::npos)
removeDependency (uuid);
else
@ -1205,7 +1204,7 @@ std::vector <int> Task::getDependencyIDs () const
{
std::vector <int> all;
for (auto& dep : split (get ("depends"), ','))
all.push_back (context.tdb2.pending.id (dep));
all.push_back (Context::getContext ().tdb2.pending.id (dep));
return all;
}
@ -1223,7 +1222,7 @@ std::vector <Task> Task::getDependencyTasks () const
for (auto& dep : split (get ("depends"), ','))
{
Task task;
context.tdb2.get (dep, task);
Context::getContext ().tdb2.get (dep, task);
all.push_back (task);
}
@ -1288,7 +1287,7 @@ bool Task::hasTag (const std::string& tag) const
#ifdef PRODUCT_TASKWARRIOR
if (tag == "UDA") return is_udaPresent ();
if (tag == "ORPHAN") return is_orphanPresent ();
if (tag == "LATEST") return id == context.tdb2.latest_id ();
if (tag == "LATEST") return id == Context::getContext ().tdb2.latest_id ();
#endif
if (tag == "PROJECT") return has ("project");
if (tag == "PRIORITY") return has ("priority");
@ -1357,7 +1356,7 @@ std::vector <std::string> Task::getUDAOrphanUUIDs () const
std::vector <std::string> orphans;
for (auto& it : data)
if (it.first.compare (0, 11, "annotation_", 11) != 0)
if (context.columns.find (it.first) == context.columns.end ())
if (Context::getContext ().columns.find (it.first) == Context::getContext ().columns.end ())
orphans.push_back (it.first);
return orphans;
@ -1574,7 +1573,7 @@ void Task::validate (bool applyDefault /* = true */)
if (Task::defaultProject != "" &&
! has ("project"))
{
if (context.columns["project"]->validate (Task::defaultProject))
if (Context::getContext ().columns["project"]->validate (Task::defaultProject))
set ("project", Task::defaultProject);
}
@ -1582,7 +1581,7 @@ void Task::validate (bool applyDefault /* = true */)
if (Task::defaultDue != "" &&
! has ("due"))
{
if (context.columns["due"]->validate (Task::defaultDue))
if (Context::getContext ().columns["due"]->validate (Task::defaultDue))
{
Duration dur (Task::defaultDue);
if (dur.toTime_t () != 0)
@ -1596,7 +1595,7 @@ void Task::validate (bool applyDefault /* = true */)
if (Task::defaultScheduled != "" &&
! has ("scheduled"))
{
if (context.columns["scheduled"]->validate (Task::defaultScheduled))
if (Context::getContext ().columns["scheduled"]->validate (Task::defaultScheduled))
{
Duration dur (Task::defaultScheduled);
if (dur.toTime_t () != 0)
@ -1610,7 +1609,7 @@ void Task::validate (bool applyDefault /* = true */)
// override with uda.(uda).default, if not specified.
// Gather a list of all UDAs with a .default value
std::vector <std::string> udas;
for (auto& var : context.config)
for (auto& var : Context::getContext ().config)
{
if (! var.first.compare (0, 4, "uda.", 4) &&
var.first.find (".default") != std::string::npos)
@ -1627,7 +1626,7 @@ void Task::validate (bool applyDefault /* = true */)
// of course only if we don't have one on the command line already
for (auto& uda : udas)
{
std::string defVal= context.config.get ("uda." + uda + ".default");
std::string defVal= Context::getContext ().config.get ("uda." + uda + ".default");
// If the default is empty, or we already have a value, skip it
if (defVal != "" && get (uda) == "")
@ -1687,7 +1686,7 @@ void Task::validate_before (const std::string& left, const std::string& right)
// if date is zero, then it is being removed (e.g. "due: wait:1day")
if (date_left > date_right && date_right.toEpoch () != 0)
context.footnote (format ("Warning: You have specified that the '{1}' date is after the '{2}' date.", left, right));
Context::getContext ().footnote (format ("Warning: You have specified that the '{1}' date is after the '{2}' date.", left, right));
}
#endif
}
@ -1886,7 +1885,7 @@ float Task::urgency_c () const
}
}
if (is_blocking && context.config.getBoolean ("urgency.inherit"))
if (is_blocking && Context::getContext ().config.getBoolean ("urgency.inherit"))
{
float prev = value;
value = std::max (value, urgency_inherit ());
@ -2069,7 +2068,7 @@ void Task::modify (modType type, bool text_required /* = false */)
std::string text = "";
bool mods = false;
for (auto& a : context.cli2._args)
for (auto& a : Context::getContext ().cli2._args)
{
if (a.hasTag ("MODIFICATION"))
{
@ -2086,22 +2085,22 @@ void Task::modify (modType type, bool text_required /* = false */)
// ::composeF4 will skip if the value is blank, but the presence of
// the attribute will prevent ::validate from applying defaults.
if ((has (name) && get (name) != "") ||
(name == "due" && context.config.has ("default.due")) ||
(name == "scheduled" && context.config.has ("default.scheduled")) ||
(name == "project" && context.config.has ("default.project")))
(name == "due" && Context::getContext ().config.has ("default.due")) ||
(name == "scheduled" && Context::getContext ().config.has ("default.scheduled")) ||
(name == "project" && Context::getContext ().config.has ("default.project")))
{
mods = true;
set (name, "");
}
context.debug (label + name + " <-- ''");
Context::getContext ().debug (label + name + " <-- ''");
}
else
{
Lexer::dequote (value);
// Get the column info. Some columns are not modifiable.
Column* column = context.columns[name];
Column* column = Context::getContext ().columns[name];
if (! column ||
! column->modifiable ())
throw format ("The '{1}' attribute does not allow a value of '{2}'.", name, value);
@ -2127,7 +2126,7 @@ void Task::modify (modType type, bool text_required /* = false */)
// Perform description/annotation substitution.
else if (a._lextype == Lexer::Type::substitution)
{
context.debug (label + "substitute " + a.attribute ("raw"));
Context::getContext ().debug (label + "substitute " + a.attribute ("raw"));
substitute (a.attribute ("from"),
a.attribute ("to"),
a.attribute ("flags"));
@ -2144,13 +2143,13 @@ void Task::modify (modType type, bool text_required /* = false */)
if (a.attribute ("sign") == "+")
{
context.debug (label + "tags <-- add '" + tag + '\'');
Context::getContext ().debug (label + "tags <-- add '" + tag + '\'');
addTag (tag);
feedback_special_tags (*this, tag);
}
else
{
context.debug (label + "tags <-- remove '" + tag + '\'');
Context::getContext ().debug (label + "tags <-- remove '" + tag + '\'');
removeTag (tag);
}
@ -2176,22 +2175,22 @@ void Task::modify (modType type, bool text_required /* = false */)
switch (type)
{
case modReplace:
context.debug (label + "description <-- '" + text + '\'');
Context::getContext ().debug (label + "description <-- '" + text + '\'');
set ("description", text);
break;
case modPrepend:
context.debug (label + "description <-- '" + text + "' + description");
Context::getContext ().debug (label + "description <-- '" + text + "' + description");
set ("description", text + ' ' + get ("description"));
break;
case modAppend:
context.debug (label + "description <-- description + '" + text + '\'');
Context::getContext ().debug (label + "description <-- description + '" + text + '\'');
set ("description", get ("description") + ' ' + text);
break;
case modAnnotate:
context.debug (label + "new annotation <-- '" + text + '\'');
Context::getContext ().debug (label + "new annotation <-- '" + text + '\'');
addAnnotation (text);
break;
}
@ -2205,7 +2204,7 @@ void Task::modify (modType type, bool text_required /* = false */)
getStatus () == originalStatus)
{
auto uuid = get ("uuid").substr (0, 8);
context.footnote (format ("Note: Modified task {1} is {2}. You may wish to make this task pending with: task {3} modify status:pending", uuid, get ("status"), uuid));
Context::getContext ().footnote (format ("Note: Modified task {1} is {2}. You may wish to make this task pending with: task {3} modify status:pending", uuid, get ("status"), uuid));
}
}
#endif