mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-06-26 10:54:26 +02:00
Code Cleanup
- Removed obsolete A3::postfix, Task::modify, Task::next_mod_group, Command::modify_task*.
This commit is contained in:
parent
e7d733881a
commit
3abff20a46
6 changed files with 0 additions and 401 deletions
100
src/A3.cpp
100
src/A3.cpp
|
@ -713,106 +713,6 @@ const A3 A3::tokenize (const A3& input) const
|
|||
return output;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Dijkstra Shunting Algorithm.
|
||||
// http://en.wikipedia.org/wiki/Shunting-yard_algorithm
|
||||
//
|
||||
// While there are tokens to be read:
|
||||
// Read a token.
|
||||
// If the token is an operator, o1, then:
|
||||
// while there is an operator token, o2, at the top of the stack, and
|
||||
// either o1 is left-associative and its precedence is less than or
|
||||
// equal to that of o2,
|
||||
// or o1 is right-associative and its precedence is less than that
|
||||
// of o2,
|
||||
// pop o2 off the stack, onto the output queue;
|
||||
// push o1 onto the stack.
|
||||
// If the token is a left parenthesis, then push it onto the stack.
|
||||
// If the token is a right parenthesis:
|
||||
// Until the token at the top of the stack is a left parenthesis, pop
|
||||
// operators off the stack onto the output queue.
|
||||
// Pop the left parenthesis from the stack, but not onto the output queue.
|
||||
// If the token at the top of the stack is a function token, pop it onto
|
||||
// the output queue.
|
||||
// If the stack runs out without finding a left parenthesis, then there
|
||||
// are mismatched parentheses.
|
||||
// If the token is a number, then add it to the output queue.
|
||||
//
|
||||
// When there are no more tokens to read:
|
||||
// While there are still operator tokens in the stack:
|
||||
// If the operator token on the top of the stack is a parenthesis, then
|
||||
// there are mismatched parentheses.
|
||||
// Pop the operator onto the output queue.
|
||||
// Exit.
|
||||
//
|
||||
const A3 A3::postfix (const A3& input) const
|
||||
{
|
||||
if (input.size () == 1)
|
||||
return input;
|
||||
|
||||
A3 converted;
|
||||
A3 op_stack;
|
||||
char type;
|
||||
int precedence;
|
||||
char associativity;
|
||||
|
||||
std::vector <Arg>::const_iterator arg;
|
||||
for (arg = input.begin (); arg != input.end (); ++arg)
|
||||
{
|
||||
if (arg->_raw == "(")
|
||||
{
|
||||
op_stack.push_back (*arg);
|
||||
}
|
||||
else if (arg->_raw == ")")
|
||||
{
|
||||
while (op_stack.size () > 0 &&
|
||||
op_stack.back ()._raw != "(")
|
||||
{
|
||||
converted.push_back (op_stack.back ());
|
||||
op_stack.pop_back ();
|
||||
}
|
||||
|
||||
if (op_stack.size ())
|
||||
op_stack.pop_back ();
|
||||
else
|
||||
throw std::string (STRING_A3_MISMATCHED_PARENS);
|
||||
}
|
||||
else if (which_operator (arg->_raw, type, precedence, associativity))
|
||||
{
|
||||
char type2;
|
||||
int precedence2;
|
||||
char associativity2;
|
||||
while (op_stack.size () > 0 &&
|
||||
which_operator (op_stack.back ()._raw, type2, precedence2, associativity2) &&
|
||||
((associativity == 'l' && precedence <= precedence2) ||
|
||||
(associativity == 'r' && precedence < precedence2)))
|
||||
{
|
||||
converted.push_back (op_stack.back ());
|
||||
op_stack.pop_back ();
|
||||
}
|
||||
|
||||
op_stack.push_back (*arg);
|
||||
}
|
||||
else
|
||||
{
|
||||
converted.push_back (*arg);
|
||||
}
|
||||
}
|
||||
|
||||
while (op_stack.size () != 0)
|
||||
{
|
||||
if (op_stack.back ()._raw == "(" ||
|
||||
op_stack.back ()._raw == ")")
|
||||
throw std::string (STRING_A3_MISMATCHED_PARENS);
|
||||
|
||||
converted.push_back (op_stack.back ());
|
||||
op_stack.pop_back ();
|
||||
}
|
||||
|
||||
converted.dump ("A3::postfix");
|
||||
return converted;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// <name>:['"][<value>]['"]
|
||||
bool A3::is_attr (Nibbler& n, Arg& arg)
|
||||
|
|
1
src/A3.h
1
src/A3.h
|
@ -59,7 +59,6 @@ public:
|
|||
bool find_command (std::string&) const;
|
||||
|
||||
const A3 tokenize (const A3&) const;
|
||||
const A3 postfix (const A3&) const;
|
||||
|
||||
static bool is_attr (Nibbler&, Arg&);
|
||||
static bool is_attmod (Nibbler&, Arg&);
|
||||
|
|
229
src/Task.cpp
229
src/Task.cpp
|
@ -1930,235 +1930,6 @@ float Task::urgency_blocking () const
|
|||
return 0.0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// TODO Obsolete
|
||||
void Task::modify (
|
||||
const A3& arguments,
|
||||
std::string& description)
|
||||
{
|
||||
// Coalesce arguments together into sets to be processed as a batch.
|
||||
unsigned int pos = 0;
|
||||
Arg arg;
|
||||
while ((*this).next_mod_group (arguments, arg, pos))
|
||||
{
|
||||
// Attributes are essentially name:value pairs, and correspond directly
|
||||
// to stored attributes.
|
||||
if (arg._category == Arg::cat_attr)
|
||||
{
|
||||
std::string name;
|
||||
std::string value;
|
||||
A3::extract_attr (arg._raw, name, value);
|
||||
if (A3::is_attribute (name, name)) // Canonicalize
|
||||
{
|
||||
// Get the column info.
|
||||
Column* column = context.columns[name];
|
||||
|
||||
if (value == "")
|
||||
{
|
||||
(*this).remove (name);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Dependencies are used as IDs.
|
||||
if (name == "depends")
|
||||
{
|
||||
// Parse IDs
|
||||
std::vector <std::string> deps;
|
||||
split (deps, value, ',');
|
||||
|
||||
// Apply or remove dendencies in turn.
|
||||
std::vector <std::string>::iterator i;
|
||||
for (i = deps.begin (); i != deps.end (); i++)
|
||||
{
|
||||
bool removal = false;
|
||||
std::string& dep = *i;
|
||||
|
||||
if (dep[0] == '-')
|
||||
{
|
||||
removal = true;
|
||||
dep = i->substr(1, std::string::npos);
|
||||
}
|
||||
|
||||
std::vector <int> ids;
|
||||
// Crude UUID check
|
||||
if (dep.length () == 36)
|
||||
{
|
||||
int id = context.tdb2.pending.id (dep);
|
||||
ids.push_back (id);
|
||||
}
|
||||
else
|
||||
A3::extract_id (dep, ids);
|
||||
|
||||
std::vector <int>::iterator id;
|
||||
for (id = ids.begin (); id != ids.end(); id++)
|
||||
if (removal)
|
||||
(*this).removeDependency (*id);
|
||||
else
|
||||
(*this).addDependency (*id);
|
||||
}
|
||||
}
|
||||
|
||||
// Dates are special, maybe.
|
||||
else if (column->type () == "date")
|
||||
{
|
||||
// All values must be eval'd first.
|
||||
A3 value_tokens;
|
||||
value_tokens.capture (value);
|
||||
value_tokens = value_tokens.postfix (value_tokens.tokenize (value_tokens));
|
||||
|
||||
E9 e (value_tokens);
|
||||
std::string result = e.evalExpression ((*this));
|
||||
context.debug (std::string ("Eval '") + value + "' --> '" + result + "'");
|
||||
|
||||
// If the date value is less than 5 years, it is a duration, not a
|
||||
// date, therefore add 'now'.
|
||||
long l = (long) strtod (result.c_str (), NULL);
|
||||
if (labs (l) < 5 * 365 * 86400)
|
||||
{
|
||||
OldDuration dur (value);
|
||||
Date now;
|
||||
now += l;
|
||||
(*this).set (name, now.toEpochString ());
|
||||
}
|
||||
else
|
||||
{
|
||||
Date d (result, context.config.get ("dateformat"));
|
||||
(*this).set (name, d.toEpochString ());
|
||||
}
|
||||
}
|
||||
|
||||
// Durations too.
|
||||
else if (name == "recur" ||
|
||||
column->type () == "duration")
|
||||
{
|
||||
// All values must be eval'd first, in this case, just to catch errors.
|
||||
A3 value_tokens;
|
||||
value_tokens.capture (value);
|
||||
value_tokens = value_tokens.postfix (value_tokens.tokenize (value_tokens));
|
||||
|
||||
E9 e (value_tokens);
|
||||
std::string result = e.evalExpression ((*this));
|
||||
context.debug (std::string ("Eval '") + value + "' --> '" + result + "'");
|
||||
|
||||
OldDuration d (value);
|
||||
|
||||
// Deliberately storing the 'raw' value, which is necessary for
|
||||
// durations like 'weekday'..
|
||||
(*this).set (name, name == "recur" ? value : result);
|
||||
}
|
||||
|
||||
// Need handling for numeric types, used by UDAs.
|
||||
else if (column->type () == "numeric")
|
||||
{
|
||||
A3 value_tokens;
|
||||
value_tokens.capture (value);
|
||||
value_tokens = value_tokens.postfix (value_tokens.tokenize (value_tokens));
|
||||
|
||||
E9 e (value_tokens);
|
||||
std::string result = e.evalExpression ((*this));
|
||||
context.debug (std::string ("Eval '") + value + "' --> '" + result + "'");
|
||||
|
||||
Nibbler n (result);
|
||||
double d;
|
||||
if (n.getNumber (d) &&
|
||||
n.depleted ())
|
||||
(*this).set (name, result);
|
||||
else
|
||||
throw format (STRING_UDA_NUMERIC, result);
|
||||
}
|
||||
|
||||
// Try to use modify method, otherwise just continue to the final option.
|
||||
else if (column->can_modify ())
|
||||
{
|
||||
// column->modify () contains the logic for the specific column
|
||||
// and returns the appropriate value for (*this).set ()
|
||||
if (column->validate (value))
|
||||
(*this).set (name, column->modify (value));
|
||||
else
|
||||
throw format (STRING_INVALID_MOD, name, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Final default action
|
||||
if (column->validate (value))
|
||||
(*this).set (name, value);
|
||||
else
|
||||
throw format (STRING_INVALID_MOD, name, value);
|
||||
}
|
||||
|
||||
// Warn about deprecated/obsolete attribute usage.
|
||||
legacyAttributeCheck (name);
|
||||
}
|
||||
}
|
||||
else
|
||||
throw format (STRING_CMD_ADD_BAD_ATTRIBUTE, name);
|
||||
}
|
||||
|
||||
// Tags need special handling because they are essentially a vector stored
|
||||
// in a single string, therefore Task::{add,remove}Tag must be called as
|
||||
// appropriate.
|
||||
else if (arg._category == Arg::cat_tag)
|
||||
{
|
||||
char type;
|
||||
std::string value;
|
||||
A3::extract_tag (arg._raw, type, value);
|
||||
|
||||
if (type == '+')
|
||||
{
|
||||
(*this).addTag (value);
|
||||
feedback_special_tags ((*this), value);
|
||||
}
|
||||
else
|
||||
(*this).removeTag (value);
|
||||
}
|
||||
|
||||
// Substitutions.
|
||||
else if (arg._category == Arg::cat_subst)
|
||||
{
|
||||
std::string from;
|
||||
std::string to;
|
||||
bool global;
|
||||
A3::extract_subst (arg._raw, from, to, global);
|
||||
(*this).substitute (from, to, global);
|
||||
}
|
||||
|
||||
// Anything else is essentially downgraded to 'word' and considered part of
|
||||
// the description.
|
||||
else
|
||||
{
|
||||
if (description.length ())
|
||||
description += " ";
|
||||
|
||||
description += arg._raw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// TODO Obsolete.
|
||||
// Special processing for modifications.
|
||||
bool Task::next_mod_group (const A3& input, Arg& arg, unsigned int& pos)
|
||||
{
|
||||
if (pos < input.size ())
|
||||
{
|
||||
arg = input[pos++];
|
||||
|
||||
if (arg._raw == "depends")
|
||||
{
|
||||
while (pos < input.size () &&
|
||||
(input[pos]._category == Arg::cat_op ||
|
||||
input[pos]._type == Arg::type_number))
|
||||
{
|
||||
arg._raw += input[pos++]._raw;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Task::modify (modType type)
|
||||
{
|
||||
|
|
|
@ -154,11 +154,6 @@ public:
|
|||
float urgency_c () const;
|
||||
float urgency ();
|
||||
|
||||
// TODO Obsolete.
|
||||
void modify (const A3&, std::string&);
|
||||
// TODO Obsolete.
|
||||
bool next_mod_group (const A3&, Arg&, unsigned int&);
|
||||
|
||||
enum modType {modReplace, modPrepend, modAppend, modAnnotate};
|
||||
void modify (modType);
|
||||
|
||||
|
|
|
@ -278,66 +278,6 @@ bool Command::displays_id () const
|
|||
return _displays_id;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// TODO Obsolete.
|
||||
// Apply the modifications in arguments to the task.
|
||||
void Command::modify_task_description_replace (Task& task, const A3& arguments)
|
||||
{
|
||||
std::string description;
|
||||
modify_task (task, arguments, description);
|
||||
|
||||
if (description.length ())
|
||||
{
|
||||
_needs_confirm = true;
|
||||
task.set ("description", description);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// TODO Obsolete.
|
||||
void Command::modify_task_description_prepend (Task& task, const A3& arguments)
|
||||
{
|
||||
std::string description;
|
||||
modify_task (task, arguments, description);
|
||||
|
||||
if (description.length ())
|
||||
task.set ("description", description + " " + task.get ("description"));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// TODO Obsolete.
|
||||
void Command::modify_task_description_append (Task& task, const A3& arguments)
|
||||
{
|
||||
std::string description;
|
||||
modify_task (task, arguments, description);
|
||||
|
||||
if (description.length ())
|
||||
task.set ("description", task.get ("description") + " " + description);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// TODO Obsolete.
|
||||
void Command::modify_task_annotate (Task& task, const A3& arguments)
|
||||
{
|
||||
std::string description;
|
||||
modify_task (task, arguments, description);
|
||||
|
||||
if (description.length ())
|
||||
task.addAnnotation (description);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// TODO Obsolete.
|
||||
// Worker function that does all the updates, but never overwrites description.
|
||||
void Command::modify_task (
|
||||
Task& task,
|
||||
const A3& arguments,
|
||||
std::string& description)
|
||||
{
|
||||
// Utilize Task::modify
|
||||
task.modify (arguments, description);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Returns true or false indicating whether to proceed with a write command, on
|
||||
// a per-task basis, after (potentially) asking for permission.
|
||||
|
|
|
@ -52,12 +52,6 @@ public:
|
|||
virtual int execute (std::string&) = 0;
|
||||
|
||||
protected:
|
||||
void modify_task_description_replace (Task&, const A3&);
|
||||
void modify_task_description_prepend (Task&, const A3&);
|
||||
void modify_task_description_append (Task&, const A3&);
|
||||
void modify_task_annotate (Task&, const A3&);
|
||||
void modify_task (Task&, const A3&, std::string&);
|
||||
|
||||
bool permission (const Task&, const std::string&, unsigned int);
|
||||
|
||||
protected:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue