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")
|
||||
// TODO Apply /mFrom/mTo/mGlobal to record.get ("annotation...")
|
||||
if (mFrom != "")
|
||||
{
|
||||
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
|
||||
|
||||
#include <string>
|
||||
#include <Record.h>
|
||||
#include "Att.h"
|
||||
|
||||
class Subst
|
||||
{
|
||||
|
@ -40,7 +40,7 @@ public:
|
|||
~Subst (); // Destructor
|
||||
|
||||
bool parse (const std::string&);
|
||||
void apply (Record&) const;
|
||||
void apply (std::string&, std::vector <Att>&) const;
|
||||
|
||||
public:
|
||||
std::string mFrom;
|
||||
|
|
1
src/T.h
1
src/T.h
|
@ -58,7 +58,6 @@ public:
|
|||
|
||||
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);
|
||||
|
|
67
src/T2.cpp
67
src/T2.cpp
|
@ -25,22 +25,33 @@
|
|||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include "Nibbler.h"
|
||||
#include "T2.h"
|
||||
#include "util.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
T2::T2 ()
|
||||
{
|
||||
/*
|
||||
mUUID = uuid ();
|
||||
*/
|
||||
// Each new task gets a 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)
|
||||
{
|
||||
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=");
|
||||
if (this != &other)
|
||||
{
|
||||
// mOne = other.mOne;
|
||||
mId = other.mId;
|
||||
}
|
||||
|
||||
return *this;
|
||||
|
@ -61,18 +72,11 @@ T2::~T2 ()
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Support FF2, FF3.
|
||||
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 ()
|
||||
{
|
||||
|
@ -80,6 +84,43 @@ std::string T2::composeCSV ()
|
|||
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
|
||||
{
|
||||
|
|
61
src/T2.h
61
src/T2.h
|
@ -29,42 +29,38 @@
|
|||
|
||||
#include <string>
|
||||
#include "Record.h"
|
||||
#include "Subst.h"
|
||||
#include "Sequence.h"
|
||||
|
||||
class T2 : public Record
|
||||
{
|
||||
public:
|
||||
T2 (); // Default constructor
|
||||
T2 (const std::string&); // Parse
|
||||
T2 (); // Default constructor
|
||||
T2 (const std::string&); // Parse
|
||||
T2& operator= (const T2&); // Assignment operator
|
||||
~T2 (); // Destructor
|
||||
~T2 (); // Destructor
|
||||
|
||||
void legacyParse (const std::string&);
|
||||
std::string composeF4 ();
|
||||
std::string composeCSV ();
|
||||
|
||||
// Status values.
|
||||
enum status {pending, completed, deleted, recurring};
|
||||
|
||||
// TODO Series of helper functions.
|
||||
// enum status {pending, completed, deleted, recurring};
|
||||
// Public data.
|
||||
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; }
|
||||
void addId (int id) { if (mId == 0) mId = id; mSequence.push_back (id); }
|
||||
|
||||
status getStatus () const { return mStatus; }
|
||||
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;
|
||||
void getRemoveTags (std::vector<std::string>&); // SPECIAL
|
||||
void addRemoveTag (const std::string&); // SPECIAL
|
||||
|
@ -74,40 +70,27 @@ public:
|
|||
void addTags (const std::vector <std::string>&);
|
||||
void removeTag (const std::string&);
|
||||
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;
|
||||
|
||||
private:
|
||||
/*
|
||||
int determineVersion (const std::string&);
|
||||
*/
|
||||
|
||||
private:
|
||||
/*
|
||||
status mStatus;
|
||||
std::string mUUID;
|
||||
*/
|
||||
int mId;
|
||||
std::vector <int> mSequence;
|
||||
std::string mDescription;
|
||||
/*
|
||||
std::vector<std::string> mTags;
|
||||
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 ();
|
||||
|
||||
annotationsT += it->getAnnotationCount ();
|
||||
std::map <time_t, std::string> annotations;
|
||||
it->getAnnotations (annotations);
|
||||
annotationsT += annotations.size ();
|
||||
|
||||
std::vector <std::string> tags;
|
||||
it->getTags (tags);
|
||||
|
|
1
src/tests/.gitignore
vendored
1
src/tests/.gitignore
vendored
|
@ -12,3 +12,4 @@ mod.t
|
|||
record.t
|
||||
stringtable.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 \
|
||||
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
|
||||
LFLAGS = -L/usr/local/lib
|
||||
OBJECTS = ../TDB.o ../T.o ../parse.o ../text.o ../Date.o ../Duration.o \
|
||||
../util.o ../Config.o ../Sequence.o ../Att.o ../Record.o ../Mod.o \
|
||||
../StringTable.o ../Subst.o ../Nibbler.o
|
||||
OBJECTS = ../TDB.o ../TDB2.o ../T.o ../T2.o ../parse.o ../text.o ../Date.o \
|
||||
../Duration.o ../util.o ../Config.o ../Sequence.o ../Att.o \
|
||||
../Record.o ../Mod.o ../StringTable.o ../Subst.o ../Nibbler.o \
|
||||
../Filter.o ../Location.o
|
||||
|
||||
all: $(PROJECT)
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
// USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#include <T.h>
|
||||
#include <T2.h>
|
||||
#include <Subst.h>
|
||||
#include <test.h>
|
||||
|
||||
|
@ -33,14 +33,18 @@ int main (int argc, char** argv)
|
|||
{
|
||||
UnitTest t (2);
|
||||
|
||||
T task;
|
||||
T2 task;
|
||||
task.set ("description", "one two three four");
|
||||
|
||||
Subst s;
|
||||
if (s.parse ("/two/TWO/"))
|
||||
{
|
||||
s.apply (task);
|
||||
t.is (task.get ("description"), "one TWO three four", "single word subst");
|
||||
std::string description = task.get ("description");
|
||||
std::vector <Att> annotations;
|
||||
task.getAnnotations (annotations);
|
||||
|
||||
s.apply (description, annotations);
|
||||
t.is (description, "one TWO three four", "single word subst");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -49,8 +53,12 @@ int main (int argc, char** argv)
|
|||
|
||||
if (s.parse ("/e /E /g"))
|
||||
{
|
||||
s.apply (task);
|
||||
t.is (task.get ("description"), "onE TWO threE four", "multiple word subst");
|
||||
std::string description = task.get ("description");
|
||||
std::vector <Att> annotations;
|
||||
task.getAnnotations (annotations);
|
||||
|
||||
s.apply (description, annotations);
|
||||
t.is (description, "onE two threE four", "multiple word subst");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
int main (int argc, char** argv)
|
||||
{
|
||||
UnitTest test (10);
|
||||
UnitTest test (9);
|
||||
|
||||
T t;
|
||||
std::string s = t.compose ();
|
||||
|
@ -88,7 +88,6 @@ int main (int argc, char** argv)
|
|||
std::string format = t.compose ();
|
||||
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 (t.getAnnotationCount (), 1, "annotation count");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue