- Removed obsolete E9, and remaining references.
This commit is contained in:
Paul Beckingham 2014-05-25 19:08:52 -04:00
parent f495e7c385
commit f908e2ae02
4 changed files with 0 additions and 865 deletions

View file

@ -16,7 +16,6 @@ set (task_SRCS A3.cpp A3.h
Dates.cpp Dates.h Dates.cpp Dates.h
Directory.cpp Directory.h Directory.cpp Directory.h
Duration.cpp Duration.h Duration.cpp Duration.h
E9.cpp E9.h
Eval.cpp Eval.h Eval.cpp Eval.h
File.cpp File.h File.cpp File.h
Filter.cpp Filter.h Filter.cpp Filter.h

View file

@ -1,785 +0,0 @@
////////////////////////////////////////////////////////////////////////////////
//
// Copyright 2006 - 2014, Paul Beckingham, Federico Hernandez.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
// http://www.opensource.org/licenses/mit-license.php
//
////////////////////////////////////////////////////////////////////////////////
#include <cmake.h>
#include <iostream>
#include <stdlib.h>
#include <Context.h>
#include <Date.h>
#include <OldDuration.h>
#include <i18n.h>
#include <text.h>
#include <E9.h>
extern Context context;
////////////////////////////////////////////////////////////////////////////////
std::ostream& operator<< (std::ostream& out, const Arg& term)
{
out << term._value << "|"
<< term._raw << "|"
<< Arg::type_name (term._type) << "|"
<< Arg::category_name (term._category);
return out;
}
////////////////////////////////////////////////////////////////////////////////
// Perform all the necessary steps prior to an eval call.
E9::E9 (const A3& args)
{
_terms = args;
_dateformat = context.config.get ("dateformat");
_dom = context.config.getBoolean ("dom");
}
////////////////////////////////////////////////////////////////////////////////
E9::~E9 ()
{
}
////////////////////////////////////////////////////////////////////////////////
bool E9::evalFilter (const Task& task)
{
if (_terms.size () == 0)
return true;
std::vector <Arg> value_stack;
eval (task, value_stack);
// Coerce result to Boolean.
Arg result = value_stack.back ();
value_stack.pop_back ();
return get_bool (coerce (result, Arg::type_bool));
}
////////////////////////////////////////////////////////////////////////////////
std::string E9::evalExpression (const Task& task)
{
if (_terms.size () == 0)
return "";
std::vector <Arg> value_stack;
eval (task, value_stack);
return value_stack.back ()._value;
}
////////////////////////////////////////////////////////////////////////////////
void E9::eval (const Task& task, std::vector <Arg>& value_stack)
{
// Case sensitivity is configurable.
bool case_sensitive = context.config.getBoolean ("search.case.sensitive");
std::vector <Arg>::const_iterator arg;
for (arg = _terms.begin (); arg != _terms.end (); ++arg)
{
if (arg->_category == Arg::cat_op)
{
Arg result;
// Unary operators.
if (arg->_raw == "!")
{
if (value_stack.size () < 1)
throw format (STRING_E9_NO_OPERANDS, "not");
Arg right = value_stack.back ();
value_stack.pop_back ();
operator_not (result, right);
}
// TODO Not sure this is correct.
// TODO No longer sure why I was unsure in the first place.
else if (arg->_raw == "-" && value_stack.size () == 1)
{
Arg right = value_stack.back ();
value_stack.pop_back ();
operator_negate (result, right);
}
// Binary operators.
else
{
if (value_stack.size () < 2)
throw format (STRING_E9_INSUFFICIENT_OP, arg->_raw);
Arg right = value_stack.back ();
value_stack.pop_back ();
Arg left = value_stack.back ();
value_stack.pop_back ();
if (arg->_raw == "and") operator_and (result, left, right);
else if (arg->_raw == "or") operator_or (result, left, right);
else if (arg->_raw == "xor") operator_xor (result, left, right);
else if (arg->_raw == "<") operator_lt (result, left, right);
else if (arg->_raw == "<=") operator_lte (result, left, right);
else if (arg->_raw == ">=") operator_gte (result, left, right);
else if (arg->_raw == ">") operator_gt (result, left, right);
else if (arg->_raw == "!=") operator_inequal (result, left, right, case_sensitive);
else if (arg->_raw == "=") operator_equal (result, left, right, case_sensitive);
else if (arg->_raw == "~") operator_match (result, left, right, case_sensitive, task);
else if (arg->_raw == "!~") operator_nomatch (result, left, right, case_sensitive, task);
else if (arg->_raw == "_hastag_") operator_hastag (result, right, false, task);
else if (arg->_raw == "_notag_") operator_hastag (result, right, true, task);
else
throw format (STRING_E9_UNSUPPORTED, arg->_raw);
}
// Store the result.
value_stack.push_back (result);
}
// Operand (non-op).
else
{
// Derive _value from _raw, and push on the stack.
Arg operand (*arg);
if (operand._category == Arg::cat_dom && _dom)
{
operand._category = Arg::cat_literal;
operand._value = context.dom.get (operand._raw, task);
}
else if (operand._type == Arg::type_date)
{
// Could be a date, could be a duration, added to 'now'.
operand._category = Arg::cat_literal;
if (operand._raw != "")
{
if (Date::valid (operand._raw, _dateformat))
operand._value = Date (operand._raw, _dateformat).toEpochString ();
else if (OldDuration::valid (operand._raw))
{
OldDuration dur (operand._raw);
Date now;
if (dur.negative ())
now -= (int)(time_t) dur;
else
now += (int)(time_t) dur;
operand._value = now.toEpochString ();
}
else
operand._value = "";
}
else
operand._value = "";
}
else if (operand._type == Arg::type_duration)
{
operand._category = Arg::cat_literal;
operand._value = (operand._raw != "")
? (std::string)OldDuration (operand._raw)
: "";
}
else
operand._value = operand._raw;
value_stack.push_back (operand);
}
}
// Check for stack remnants.
if (value_stack.size () != 1)
throw std::string (STRING_E9_MORE_OP);
}
////////////////////////////////////////////////////////////////////////////////
bool E9::eval_match (Arg& left, Arg& right, bool case_sensitive)
{
if (right._category == Arg::cat_rx)
{
left = coerce (left, Arg::type_string);
right = coerce (right, Arg::type_string);
// Create a cached entry, if it does not already exist.
if (_regexes.find (right._value) == _regexes.end ())
_regexes[right._value] = RX (right._value, case_sensitive);
if (_regexes[right._value].match (left._value))
return true;
}
else
{
// TODO Is there a danger of a raw date '1234567890' matching '234'?
left = coerce (left, Arg::type_string);
right = coerce (right, Arg::type_string);
if (find (left._value, right._value, (bool) case_sensitive) != std::string::npos)
return true;
}
return false;
}
////////////////////////////////////////////////////////////////////////////////
void E9::operator_not (Arg& result, Arg& right)
{
result = coerce (right, Arg::type_bool);
if (result._value == "true")
result._value = "false";
else
result._value = "true";
}
////////////////////////////////////////////////////////////////////////////////
void E9::operator_negate (Arg& result, Arg& right)
{
result = coerce (right, Arg::type_number);
result._value = format (- strtod (result._value.c_str (), NULL));
}
////////////////////////////////////////////////////////////////////////////////
void E9::operator_and (Arg& result, Arg& left, Arg& right)
{
result._value = "false";
result._type = Arg::type_bool;
if (coerce (left, Arg::type_bool)._value == "true" &&
coerce (right, Arg::type_bool)._value == "true" )
{
result._value = "true";
}
}
////////////////////////////////////////////////////////////////////////////////
void E9::operator_or (Arg& result, Arg& left, Arg& right)
{
result._value = "false";
result._type = Arg::type_bool;
if (coerce (left, Arg::type_bool)._value == "true" ||
coerce (right, Arg::type_bool)._value == "true" )
{
result._value = "true";
}
}
////////////////////////////////////////////////////////////////////////////////
void E9::operator_xor (Arg& result, Arg& left, Arg& right)
{
result._value = "false";
result._type = Arg::type_bool;
bool bool_left = coerce (left, Arg::type_bool)._value == "true";
bool bool_right = coerce (right, Arg::type_bool)._value == "true";
if ((bool_left && !bool_right) ||
(!bool_left && bool_right))
{
result._value = "true";
}
}
////////////////////////////////////////////////////////////////////////////////
void E9::operator_lt (Arg& result, Arg& left, Arg& right)
{
if (left._raw == "priority")
{
if (left._value != "H" && right._value == "H") result._value = "true";
else if (left._value == "L" && right._value == "M") result._value = "true";
else if (left._value == "" && right._value != "") result._value = "true";
else result._value = "false";
}
else if (left._type == Arg::type_date ||
right._type == Arg::type_date)
{
if (left._value == "" ||
right._value == "")
result._value = "false";
else
{
Date left_date (left._value, _dateformat);
Date right_date (right._value, _dateformat);
result._value = (left_date < right_date)
? "true"
: "false";
}
}
else if (left._type == Arg::type_duration ||
right._type == Arg::type_duration)
{
if (left._value == "" ||
right._value == "")
result._value = "false";
else
{
OldDuration left_duration (left._value);
OldDuration right_duration (right._value);
result._value = (left_duration < right_duration)
? "true"
: "false";
}
}
else if (left._type == Arg::type_number ||
right._type == Arg::type_number)
{
float left_number = strtof (left._value.c_str (), NULL);
float right_number = strtof (right._value.c_str (), NULL);
result._value = (left_number < right_number)
? "true"
: "false";
}
else
{
result._value = (left._value < right._value)
? "true"
: "false";
}
result._type = Arg::type_bool;
}
////////////////////////////////////////////////////////////////////////////////
void E9::operator_lte (Arg& result, Arg& left, Arg& right)
{
if (left._raw == "priority")
{
if (left._value == right._value ) result._value = "true";
else if ( right._value == "H") result._value = "true";
else if (left._value == "L" && right._value == "M") result._value = "true";
else if (left._value == "" ) result._value = "true";
else result._value = "false";
}
else if (left._type == Arg::type_date ||
right._type == Arg::type_date)
{
if (left._value == "" ||
right._value == "")
result._value = "false";
else
{
Date left_date (left._value, _dateformat);
Date right_date (right._value, _dateformat);
result._value = (left_date <= right_date)
? "true"
: "false";
}
}
else if (left._type == Arg::type_duration ||
right._type == Arg::type_duration)
{
if (left._value == "" ||
right._value == "")
result._value = "false";
else
{
OldDuration left_duration (left._value);
OldDuration right_duration (right._value);
result._value = (left_duration <= right_duration)
? "true"
: "false";
}
}
else if (left._type == Arg::type_number ||
right._type == Arg::type_number)
{
float left_number = strtof (left._value.c_str (), NULL);
float right_number = strtof (right._value.c_str (), NULL);
result._value = (left_number <= right_number)
? "true"
: "false";
}
else
{
result._value = (left._value <= right._value)
? "true"
: "false";
}
result._type = Arg::type_bool;
}
////////////////////////////////////////////////////////////////////////////////
void E9::operator_gte (Arg& result, Arg& left, Arg& right)
{
if (left._raw == "priority")
{
if (left._value == right._value ) result._value = "true";
else if (left._value == "H" ) result._value = "true";
else if (left._value == "M" && right._value == "L") result._value = "true";
else if ( right._value == "" ) result._value = "true";
else result._value = "false";
}
else if (left._type == Arg::type_date ||
right._type == Arg::type_date)
{
if (left._value == "" ||
right._value == "")
result._value = "false";
else
{
Date left_date (left._value, _dateformat);
Date right_date (right._value, _dateformat);
result._value = (left_date >= right_date)
? "true"
: "false";
}
}
else if (left._type == Arg::type_duration ||
right._type == Arg::type_duration)
{
if (left._value == "" ||
right._value == "")
result._value = "false";
else
{
OldDuration left_duration (left._value);
OldDuration right_duration (right._value);
result._value = (left_duration >= right_duration)
? "true"
: "false";
}
}
else if (left._type == Arg::type_number ||
right._type == Arg::type_number)
{
float left_number = strtof (left._value.c_str (), NULL);
float right_number = strtof (right._value.c_str (), NULL);
result._value = (left_number >= right_number)
? "true"
: "false";
}
else
{
result._value = (left._value >= right._value)
? "true"
: "false";
}
result._type = Arg::type_bool;
}
////////////////////////////////////////////////////////////////////////////////
void E9::operator_gt (Arg& result, Arg& left, Arg& right)
{
if (left._raw == "priority")
{
if (left._value == "H" && right._value != "H") result._value = "true";
else if (left._value == "M" && right._value == "L") result._value = "true";
else if (left._value != "" && right._value == "") result._value = "true";
else result._value = "false";
}
else if (left._type == Arg::type_date ||
right._type == Arg::type_date)
{
if (left._value == "" ||
right._value == "")
result._value = "false";
else
{
Date left_date (left._value, _dateformat);
Date right_date (right._value, _dateformat);
result._value = result._value = (left_date > right_date)
? "true"
: "false";
}
}
else if (left._type == Arg::type_duration ||
right._type == Arg::type_duration)
{
if (left._value == "" ||
right._value == "")
result._value = "false";
else
{
OldDuration left_duration (left._value);
OldDuration right_duration (right._value);
result._value = result._value = (left_duration > right_duration)
? "true"
: "false";
}
}
else if (left._type == Arg::type_number ||
right._type == Arg::type_number)
{
float left_number = strtof (left._value.c_str (), NULL);
float right_number = strtof (right._value.c_str (), NULL);
result._value = (left_number > right_number)
? "true"
: "false";
}
else
{
result._value = (left._value > right._value)
? "true"
: "false";
}
result._type = Arg::type_bool;
}
////////////////////////////////////////////////////////////////////////////////
void E9::operator_inequal (
Arg& result,
Arg& left,
Arg& right,
bool case_sensitive)
{
operator_equal (result, left, right, case_sensitive);
result._value = result._value == "false"
? "true"
: "false";
}
////////////////////////////////////////////////////////////////////////////////
void E9::operator_equal (
Arg& result,
Arg& left,
Arg& right,
bool case_sensitive)
{
// Assume failure.
result._value = "false";
result._type = Arg::type_bool;
// 'project' is matched leftmost.
if (left._raw == "project")
{
// Bug 856.
//
// Special case for checking absent projects. Without the explicit "" check
// the right._value.length() is used, which is 0, and therefore generates
// a false match.
if (right._value == "")
{
if (left._value == "")
result._value = "true";
}
else
{
unsigned int right_len = right._value.length ();
if (compare (right._value,
(right_len < left._value.length ()
? left._value.substr (0, right_len)
: left._value),
case_sensitive))
{
result._value = "true";
}
}
}
// Dates. Note that missing data causes processing to transfer to the generic
// string comparison below.
else if ((left._type == Arg::type_date ||
right._type == Arg::type_date) &&
left._value != "" &&
right._value != "")
{
Date left_date (left._value, _dateformat);
Date right_date (right._value, _dateformat);
result._value = (left_date == right_date)
? "true"
: "false";
}
// Case-insensitive comparison for status. Fixes #1110.
// Also priority, fixing #1154.
else if (left._raw == "status" ||
left._raw == "priority")
{
result._value = compare (left._value, right._value, false)
? "true"
: "false";
}
// Regular equality matching.
else
{
result._value = compare (left._value, right._value, case_sensitive)
? "true"
: "false";
}
}
////////////////////////////////////////////////////////////////////////////////
// Match may occur in description or any annotation. Short circuits.
void E9::operator_match (
Arg& result,
Arg& left,
Arg& right,
bool case_sensitive,
const Task& task)
{
result._type = Arg::type_bool;
if (eval_match (left, right, case_sensitive))
{
result._value = "true";
}
else if (left._raw == "description")
{
std::map <std::string, std::string> annotations;
task.getAnnotations (annotations);
std::map <std::string, std::string>::iterator a;
for (a = annotations.begin (); a != annotations.end (); ++a)
{
// Clone 'left', override _value.
Arg alternate (left);
alternate._value = a->second;
if (eval_match (alternate, right, case_sensitive))
{
result._value = "true";
break;
}
}
}
else
result._value = "false";
}
////////////////////////////////////////////////////////////////////////////////
// Match may not occur in description or any annotation. Short circuits.
void E9::operator_nomatch (
Arg& result,
Arg& left,
Arg& right,
bool case_sensitive,
const Task& task)
{
result._type = Arg::type_bool;
result._value = "true";
if (eval_match (left, right, case_sensitive))
{
result._value = "false";
}
else if (left._raw == "description")
{
std::map <std::string, std::string> annotations;
task.getAnnotations (annotations);
std::map <std::string, std::string>::iterator a;
for (a = annotations.begin (); a != annotations.end (); ++a)
{
// Clone 'left', override _value.
Arg alternate (left);
alternate._value = a->second;
if (eval_match (alternate, right, case_sensitive))
{
result._value = "false";
break;
}
}
}
}
////////////////////////////////////////////////////////////////////////////////
void E9::operator_hastag (
Arg& result,
Arg& right,
bool invert,
const Task& task)
{
result._type = Arg::type_bool;
if (task.hasTag (right._raw))
result._value = invert ? "false" : "true";
else
result._value = invert ? "true" : "false";
}
////////////////////////////////////////////////////////////////////////////////
const Arg E9::coerce (const Arg& input, const Arg::type type)
{
Arg result;
if (type == Arg::type_bool)
{
result._raw = input._raw;
result._value = get_bool (input) ? "true" : "false";
result._type = Arg::type_bool;
result._category = input._category;
}
else if (type == Arg::type_string)
{
// TODO Convert date?
result._raw = input._raw;
result._value = input._value;
result._type = Arg::type_string;
result._category = input._category;
}
else if (type == Arg::type_number)
{
result._raw = input._raw;
result._value = input._value;
result._type = Arg::type_number;
result._category = input._category;
}
// TODO Date
// TODO OldDuration
else
{
result = input;
}
return result;
}
////////////////////////////////////////////////////////////////////////////////
bool E9::get_bool (const Arg& input)
{
std::string value = lowerCase (input._value);
if (value == "true" ||
value == "t" ||
value == "1" ||
value == "+" ||
value == "y" ||
value == "yes" ||
value == "on" ||
value == "enable" ||
value == "enabled")
return true;
return false;
}
////////////////////////////////////////////////////////////////////////////////

View file

@ -1,77 +0,0 @@
////////////////////////////////////////////////////////////////////////////////
//
// Copyright 2006 - 2014, Paul Beckingham, Federico Hernandez.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
// http://www.opensource.org/licenses/mit-license.php
//
////////////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_E9
#define INCLUDED_E9
#include <string>
#include <A3.h>
#include <Task.h>
#include <RX.h>
class E9
{
public:
E9 (const A3&);
~E9 ();
bool evalFilter (const Task&);
std::string evalExpression (const Task&);
private:
void eval (const Task&, std::vector <Arg>&);
bool eval_match (Arg&, Arg&, bool);
// Unary.
void operator_not (Arg&, Arg&);
void operator_negate (Arg&, Arg&);
// Binary.
void operator_and (Arg&, Arg&, Arg&);
void operator_or (Arg&, Arg&, Arg&);
void operator_xor (Arg&, Arg&, Arg&);
void operator_lt (Arg&, Arg&, Arg&);
void operator_lte (Arg&, Arg&, Arg&);
void operator_gte (Arg&, Arg&, Arg&);
void operator_gt (Arg&, Arg&, Arg&);
void operator_inequal (Arg&, Arg&, Arg&, bool);
void operator_equal (Arg&, Arg&, Arg&, bool);
void operator_match (Arg&, Arg&, Arg&, bool, const Task&);
void operator_nomatch (Arg&, Arg&, Arg&, bool, const Task&);
void operator_hastag (Arg&, Arg&, bool, const Task&);
const Arg coerce (const Arg&, const Arg::type);
bool get_bool (const Arg&);
private:
std::vector <Arg> _terms;
std::map <std::string, RX> _regexes;
std::string _dateformat;
bool _dom;
};
#endif
////////////////////////////////////////////////////////////////////////////////

View file

@ -51,8 +51,6 @@
#ifdef PRODUCT_TASKWARRIOR #ifdef PRODUCT_TASKWARRIOR
#include <main.h> #include <main.h>
// TODO Obsolete
#include <E9.h>
#include <Eval.h> #include <Eval.h>
#include <Variant.h> #include <Variant.h>
#include <Filter.h> #include <Filter.h>