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:
Paul Beckingham 2009-05-31 23:43:11 -04:00
parent ccff27b535
commit 7248267a72
10 changed files with 149 additions and 71 deletions

View file

@ -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;
}
}
}
}
}
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View file

@ -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;

View file

@ -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);

View file

@ -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
{ {

View file

@ -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;
*/ */
}; };

View file

@ -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);

View file

@ -12,3 +12,4 @@ mod.t
record.t record.t
stringtable.t stringtable.t
nibbler.t nibbler.t
subst.t

View file

@ -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)

View file

@ -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
{ {

View file

@ -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;
} }