mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-06-26 10:54:26 +02:00
Enhancements - T2 & Subst
- Implemented more helper functions in T2, prior to integration. - Completed Subst. - Completed Subst unit tests. - Eliminated T::getAnnotationCount.
This commit is contained in:
parent
ccff27b535
commit
7248267a72
10 changed files with 149 additions and 71 deletions
|
@ -103,10 +103,54 @@ bool Subst::parse (const std::string& input)
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void Subst::apply (Record& record) const
|
void Subst::apply (
|
||||||
|
std::string& description,
|
||||||
|
std::vector <Att>& annotations) const
|
||||||
{
|
{
|
||||||
// TODO Apply /mFrom/mTo/mGlobal to record.get ("description")
|
if (mFrom != "")
|
||||||
// TODO Apply /mFrom/mTo/mGlobal to record.get ("annotation...")
|
{
|
||||||
|
std::string::size_type pattern;
|
||||||
|
|
||||||
|
if (mGlobal)
|
||||||
|
{
|
||||||
|
// Perform all subs on description.
|
||||||
|
while ((pattern = description.find (mFrom)) != std::string::npos)
|
||||||
|
description.replace (pattern, mFrom.length (), mTo);
|
||||||
|
|
||||||
|
// Perform all subs on annotations.
|
||||||
|
std::vector <Att>::iterator i;
|
||||||
|
for (i = annotations.begin (); i != annotations.end (); ++i)
|
||||||
|
{
|
||||||
|
std::string description = i->value ();
|
||||||
|
while ((pattern = description.find (mFrom)) != std::string::npos)
|
||||||
|
{
|
||||||
|
description.replace (pattern, mFrom.length (), mTo);
|
||||||
|
i->value (description);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Perform first description substitution.
|
||||||
|
if ((pattern = description.find (mFrom)) != std::string::npos)
|
||||||
|
description.replace (pattern, mFrom.length (), mTo);
|
||||||
|
|
||||||
|
// Failing that, perform the first annotation substitution.
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::vector <Att>::iterator i;
|
||||||
|
for (i = annotations.begin (); i != annotations.end (); ++i)
|
||||||
|
{
|
||||||
|
std::string description = i->value ();
|
||||||
|
if ((pattern = description.find (mFrom)) != std::string::npos)
|
||||||
|
{
|
||||||
|
description.replace (pattern, mFrom.length (), mTo);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
#define INCLUDED_SUBST
|
#define INCLUDED_SUBST
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <Record.h>
|
#include "Att.h"
|
||||||
|
|
||||||
class Subst
|
class Subst
|
||||||
{
|
{
|
||||||
|
@ -40,7 +40,7 @@ public:
|
||||||
~Subst (); // Destructor
|
~Subst (); // Destructor
|
||||||
|
|
||||||
bool parse (const std::string&);
|
bool parse (const std::string&);
|
||||||
void apply (Record&) const;
|
void apply (std::string&, std::vector <Att>&) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::string mFrom;
|
std::string mFrom;
|
||||||
|
|
1
src/T.h
1
src/T.h
|
@ -58,7 +58,6 @@ public:
|
||||||
|
|
||||||
const std::string getDescription () const { return mDescription; }
|
const std::string getDescription () const { return mDescription; }
|
||||||
void setDescription (const std::string& description) { mDescription = description; }
|
void setDescription (const std::string& description) { mDescription = description; }
|
||||||
int getAnnotationCount () const { return mAnnotations.size (); }
|
|
||||||
|
|
||||||
void getSubstitution (std::string&, std::string&, bool&) const;
|
void getSubstitution (std::string&, std::string&, bool&) const;
|
||||||
void setSubstitution (const std::string&, const std::string&, bool);
|
void setSubstitution (const std::string&, const std::string&, bool);
|
||||||
|
|
67
src/T2.cpp
67
src/T2.cpp
|
@ -25,22 +25,33 @@
|
||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "Nibbler.h"
|
#include "Nibbler.h"
|
||||||
#include "T2.h"
|
#include "T2.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
T2::T2 ()
|
T2::T2 ()
|
||||||
{
|
{
|
||||||
/*
|
// Each new task gets a uuid.
|
||||||
mUUID = uuid ();
|
set ("uuid", uuid ());
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Attempt an FF4 parse first, using Record::parse, and in the event of an error
|
||||||
|
// try a legacy parse (F3, FF2). Note that FF1 is no longer supported.
|
||||||
T2::T2 (const std::string& input)
|
T2::T2 (const std::string& input)
|
||||||
{
|
{
|
||||||
parse (input);
|
try
|
||||||
|
{
|
||||||
|
parse (input);
|
||||||
|
}
|
||||||
|
|
||||||
|
catch (std::string& e)
|
||||||
|
{
|
||||||
|
legacyParse (input);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -49,7 +60,7 @@ T2& T2::operator= (const T2& other)
|
||||||
throw std::string ("unimplemented T2::operator=");
|
throw std::string ("unimplemented T2::operator=");
|
||||||
if (this != &other)
|
if (this != &other)
|
||||||
{
|
{
|
||||||
// mOne = other.mOne;
|
mId = other.mId;
|
||||||
}
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -61,18 +72,11 @@ T2::~T2 ()
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Support FF2, FF3.
|
||||||
void T2::legacyParse (const std::string& input)
|
void T2::legacyParse (const std::string& input)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// [name:value, name:"value",name:[name:value,name:value]]
|
|
||||||
std::string T2::composeF4 ()
|
|
||||||
{
|
|
||||||
throw std::string ("unimplemented T2::composeF4");
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
std::string T2::composeCSV ()
|
std::string T2::composeCSV ()
|
||||||
{
|
{
|
||||||
|
@ -80,6 +84,43 @@ std::string T2::composeCSV ()
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
void T2::getAnnotations (std::vector <Att>& annotations) const
|
||||||
|
{
|
||||||
|
annotations.clear ();
|
||||||
|
|
||||||
|
Record::const_iterator ci;
|
||||||
|
for (ci = this->begin (); ci != this->end (); ++ci)
|
||||||
|
if (ci->first.substr (0, 11) == "annotation_")
|
||||||
|
annotations.push_back (ci->second);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
void T2::setAnnotations (const std::vector <Att>& annotations)
|
||||||
|
{
|
||||||
|
// Erase old annotations.
|
||||||
|
Record::iterator i;
|
||||||
|
for (i = this->begin (); i != this->end (); ++i)
|
||||||
|
if (i->first.substr (0, 11) == "annotation_")
|
||||||
|
this->erase (i);
|
||||||
|
|
||||||
|
std::vector <Att>::const_iterator ci;
|
||||||
|
for (ci = annotations.begin (); ci != annotations.end (); ++ci)
|
||||||
|
(*this)[ci->name ()] = *ci;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// The timestamp is part of the name:
|
||||||
|
// annotation_1234567890:"..."
|
||||||
|
//
|
||||||
|
void T2::addAnnotation (const std::string& description)
|
||||||
|
{
|
||||||
|
std::stringstream s;
|
||||||
|
s << "annotation_" << time (NULL);
|
||||||
|
|
||||||
|
(*this)[s.str ()] = Att (s.str (), description);
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
bool T2::validate () const
|
bool T2::validate () const
|
||||||
{
|
{
|
||||||
|
|
61
src/T2.h
61
src/T2.h
|
@ -29,42 +29,38 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "Record.h"
|
#include "Record.h"
|
||||||
|
#include "Subst.h"
|
||||||
|
#include "Sequence.h"
|
||||||
|
|
||||||
class T2 : public Record
|
class T2 : public Record
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
T2 (); // Default constructor
|
T2 (); // Default constructor
|
||||||
T2 (const std::string&); // Parse
|
T2 (const std::string&); // Parse
|
||||||
T2& operator= (const T2&); // Assignment operator
|
T2& operator= (const T2&); // Assignment operator
|
||||||
~T2 (); // Destructor
|
~T2 (); // Destructor
|
||||||
|
|
||||||
void legacyParse (const std::string&);
|
void legacyParse (const std::string&);
|
||||||
std::string composeF4 ();
|
|
||||||
std::string composeCSV ();
|
std::string composeCSV ();
|
||||||
|
|
||||||
|
// Status values.
|
||||||
|
enum status {pending, completed, deleted, recurring};
|
||||||
|
|
||||||
// TODO Series of helper functions.
|
// Public data.
|
||||||
// enum status {pending, completed, deleted, recurring};
|
Sequence sequence;
|
||||||
|
Subst subst;
|
||||||
|
|
||||||
|
// Series of helper functions.
|
||||||
|
int getId () const { return mId; }
|
||||||
|
void setId (int id) { mId = id; sequence.push_back (id); }
|
||||||
|
|
||||||
/*
|
/*
|
||||||
std::string getUUID () const { return mUUID; }
|
|
||||||
void setUUID (const std::string& uuid) { mUUID = uuid; }
|
|
||||||
|
|
||||||
int getId () const { return mId; }
|
|
||||||
void setId (int id) { mId = id; mSequence.push_back (id); }
|
|
||||||
std::vector <int> getAllIds () const { return mSequence; }
|
std::vector <int> getAllIds () const { return mSequence; }
|
||||||
void addId (int id) { if (mId == 0) mId = id; mSequence.push_back (id); }
|
void addId (int id) { if (mId == 0) mId = id; mSequence.push_back (id); }
|
||||||
|
|
||||||
status getStatus () const { return mStatus; }
|
status getStatus () const { return mStatus; }
|
||||||
void setStatus (status s) { mStatus = s; }
|
void setStatus (status s) { mStatus = s; }
|
||||||
|
|
||||||
const std::string getDescription () const { return mDescription; }
|
|
||||||
void setDescription (const std::string& description) { mDescription = description; }
|
|
||||||
int getAnnotationCount () const { return mAnnotations.size (); }
|
|
||||||
|
|
||||||
void getSubstitution (std::string&, std::string&, bool&) const;
|
|
||||||
void setSubstitution (const std::string&, const std::string&, bool);
|
|
||||||
|
|
||||||
bool hasTag (const std::string&) const;
|
bool hasTag (const std::string&) const;
|
||||||
void getRemoveTags (std::vector<std::string>&); // SPECIAL
|
void getRemoveTags (std::vector<std::string>&); // SPECIAL
|
||||||
void addRemoveTag (const std::string&); // SPECIAL
|
void addRemoveTag (const std::string&); // SPECIAL
|
||||||
|
@ -74,40 +70,27 @@ public:
|
||||||
void addTags (const std::vector <std::string>&);
|
void addTags (const std::vector <std::string>&);
|
||||||
void removeTag (const std::string&);
|
void removeTag (const std::string&);
|
||||||
void removeTags ();
|
void removeTags ();
|
||||||
|
|
||||||
void getAttributes (std::map<std::string, std::string>&);
|
|
||||||
const std::string getAttribute (const std::string&);
|
|
||||||
void setAttribute (const std::string&, const std::string&);
|
|
||||||
void removeAttribute (const std::string&);
|
|
||||||
|
|
||||||
void getAnnotations (std::map <time_t, std::string>&) const;
|
|
||||||
void setAnnotations (const std::map <time_t, std::string>&);
|
|
||||||
void addAnnotation (const std::string&);
|
|
||||||
|
|
||||||
const std::string compose () const;
|
|
||||||
const std::string composeCSV ();
|
|
||||||
void parse (const std::string&);
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
void getAnnotations (std::vector <Att>&) const;
|
||||||
|
void setAnnotations (const std::vector <Att>&);
|
||||||
|
void addAnnotation (const std::string&);
|
||||||
|
|
||||||
bool validate () const;
|
bool validate () const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
/*
|
||||||
int determineVersion (const std::string&);
|
int determineVersion (const std::string&);
|
||||||
|
*/
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*
|
/*
|
||||||
status mStatus;
|
status mStatus;
|
||||||
std::string mUUID;
|
*/
|
||||||
int mId;
|
int mId;
|
||||||
std::vector <int> mSequence;
|
/*
|
||||||
std::string mDescription;
|
|
||||||
std::vector<std::string> mTags;
|
std::vector<std::string> mTags;
|
||||||
std::vector<std::string> mRemoveTags;
|
std::vector<std::string> mRemoveTags;
|
||||||
std::map<std::string, std::string> mAttributes;
|
|
||||||
std::string mFrom;
|
|
||||||
std::string mTo;
|
|
||||||
bool mGlobal;
|
|
||||||
std::map <time_t, std::string> mAnnotations;
|
|
||||||
*/
|
*/
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2145,7 +2145,9 @@ std::string handleReportStats (TDB& tdb, T& task, Config& conf)
|
||||||
|
|
||||||
descLength += it->getDescription ().length ();
|
descLength += it->getDescription ().length ();
|
||||||
|
|
||||||
annotationsT += it->getAnnotationCount ();
|
std::map <time_t, std::string> annotations;
|
||||||
|
it->getAnnotations (annotations);
|
||||||
|
annotationsT += annotations.size ();
|
||||||
|
|
||||||
std::vector <std::string> tags;
|
std::vector <std::string> tags;
|
||||||
it->getTags (tags);
|
it->getTags (tags);
|
||||||
|
|
1
src/tests/.gitignore
vendored
1
src/tests/.gitignore
vendored
|
@ -12,3 +12,4 @@ mod.t
|
||||||
record.t
|
record.t
|
||||||
stringtable.t
|
stringtable.t
|
||||||
nibbler.t
|
nibbler.t
|
||||||
|
subst.t
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
PROJECT = t.t tdb.t date.t duration.t t.benchmark.t text.t autocomplete.t \
|
PROJECT = t.t tdb.t date.t duration.t t.benchmark.t text.t autocomplete.t \
|
||||||
parse.t seq.t att.t mod.t stringtable.t record.t nibbler.t # subst.t
|
parse.t seq.t att.t mod.t stringtable.t record.t nibbler.t subst.t
|
||||||
CFLAGS = -I. -I.. -Wall -pedantic -ggdb3 -fno-rtti
|
CFLAGS = -I. -I.. -Wall -pedantic -ggdb3 -fno-rtti
|
||||||
LFLAGS = -L/usr/local/lib
|
LFLAGS = -L/usr/local/lib
|
||||||
OBJECTS = ../TDB.o ../T.o ../parse.o ../text.o ../Date.o ../Duration.o \
|
OBJECTS = ../TDB.o ../TDB2.o ../T.o ../T2.o ../parse.o ../text.o ../Date.o \
|
||||||
../util.o ../Config.o ../Sequence.o ../Att.o ../Record.o ../Mod.o \
|
../Duration.o ../util.o ../Config.o ../Sequence.o ../Att.o \
|
||||||
../StringTable.o ../Subst.o ../Nibbler.o
|
../Record.o ../Mod.o ../StringTable.o ../Subst.o ../Nibbler.o \
|
||||||
|
../Filter.o ../Location.o
|
||||||
|
|
||||||
all: $(PROJECT)
|
all: $(PROJECT)
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
// USA
|
// USA
|
||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
#include <T.h>
|
#include <T2.h>
|
||||||
#include <Subst.h>
|
#include <Subst.h>
|
||||||
#include <test.h>
|
#include <test.h>
|
||||||
|
|
||||||
|
@ -33,14 +33,18 @@ int main (int argc, char** argv)
|
||||||
{
|
{
|
||||||
UnitTest t (2);
|
UnitTest t (2);
|
||||||
|
|
||||||
T task;
|
T2 task;
|
||||||
task.set ("description", "one two three four");
|
task.set ("description", "one two three four");
|
||||||
|
|
||||||
Subst s;
|
Subst s;
|
||||||
if (s.parse ("/two/TWO/"))
|
if (s.parse ("/two/TWO/"))
|
||||||
{
|
{
|
||||||
s.apply (task);
|
std::string description = task.get ("description");
|
||||||
t.is (task.get ("description"), "one TWO three four", "single word subst");
|
std::vector <Att> annotations;
|
||||||
|
task.getAnnotations (annotations);
|
||||||
|
|
||||||
|
s.apply (description, annotations);
|
||||||
|
t.is (description, "one TWO three four", "single word subst");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -49,8 +53,12 @@ int main (int argc, char** argv)
|
||||||
|
|
||||||
if (s.parse ("/e /E /g"))
|
if (s.parse ("/e /E /g"))
|
||||||
{
|
{
|
||||||
s.apply (task);
|
std::string description = task.get ("description");
|
||||||
t.is (task.get ("description"), "onE TWO threE four", "multiple word subst");
|
std::vector <Att> annotations;
|
||||||
|
task.getAnnotations (annotations);
|
||||||
|
|
||||||
|
s.apply (description, annotations);
|
||||||
|
t.is (description, "onE two threE four", "multiple word subst");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
int main (int argc, char** argv)
|
int main (int argc, char** argv)
|
||||||
{
|
{
|
||||||
UnitTest test (10);
|
UnitTest test (9);
|
||||||
|
|
||||||
T t;
|
T t;
|
||||||
std::string s = t.compose ();
|
std::string s = t.compose ();
|
||||||
|
@ -88,7 +88,6 @@ int main (int argc, char** argv)
|
||||||
std::string format = t.compose ();
|
std::string format = t.compose ();
|
||||||
test.is (format.substr (36, 20), " - [foo] [bar:baz] [", "compose tag, attribute");
|
test.is (format.substr (36, 20), " - [foo] [bar:baz] [", "compose tag, attribute");
|
||||||
test.is (format.substr (66, 16), ":\"woof\"] sample\n", "compose annotation");
|
test.is (format.substr (66, 16), ":\"woof\"] sample\n", "compose annotation");
|
||||||
test.is (t.getAnnotationCount (), 1, "annotation count");
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue