diff --git a/src/Att.cpp b/src/Att.cpp index a96c16a82..df0b2ba16 100644 --- a/src/Att.cpp +++ b/src/Att.cpp @@ -25,6 +25,8 @@ // //////////////////////////////////////////////////////////////////////////////// +#include +#include #include "Att.h" //////////////////////////////////////////////////////////////////////////////// @@ -44,6 +46,18 @@ Att::Att (const std::string& name, const std::string& value) mMods.clear (); } +//////////////////////////////////////////////////////////////////////////////// +Att::Att (const std::string& name, int value) +{ + mName = name; + + std::stringstream s; + s << value; + mValue = s.str (); + + mMods.clear (); +} + //////////////////////////////////////////////////////////////////////////////// Att::Att (const Att& other) { @@ -55,7 +69,6 @@ Att::Att (const Att& other) //////////////////////////////////////////////////////////////////////////////// Att& Att::operator= (const Att& other) { - throw std::string ("unimplemented Att::operator="); if (this != &other) { mName = other.mName; @@ -73,21 +86,43 @@ Att::~Att () //////////////////////////////////////////////////////////////////////////////// // Parse the following forms: -// name [[.mod] ...] : [value] +// name [[.mod] ...] : " [value] " void Att::parse (const std::string& input) { - throw std::string ("unimplemented Att::parse"); + mName = ""; + mValue = ""; + mMods.clear (); + + std::string::size_type colon = input.find (":"); + if (colon != std::string::npos) + { + std::string name = input.substr (0, colon); + // TODO Are there mods? + mName = name; + + std::string value = input.substr (colon + 1, std::string::npos); + dequote (value); + decode (value); + mValue = value; + } } //////////////////////////////////////////////////////////////////////////////// // name : " value " std::string Att::composeF4 () const { - std::string value = mValue; - encode (value); - enquote (value); + std::string output = ""; - return mName + ":" + value; + if (mName != "" && mValue != "") + { + std::string value = mValue; + encode (value); + enquote (value); + + output += mName + ":" + value; + } + + return output; } //////////////////////////////////////////////////////////////////////////////// @@ -123,35 +158,15 @@ void Att::value (const std::string& value) //////////////////////////////////////////////////////////////////////////////// int Att::value_int () const { - throw std::string ("unimplemented Att::value_int"); - return 0; + return ::atoi (mValue.c_str ()); } //////////////////////////////////////////////////////////////////////////////// -void Att::value_int (int) +void Att::value_int (int value) { - throw std::string ("unimplemented Att::value_int"); -} - -//////////////////////////////////////////////////////////////////////////////// -bool Att::filter () const -{ - throw std::string ("unimplemented filter"); - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -bool Att::required () const -{ - throw std::string ("unimplemented Att::required"); - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -bool Att::reserved () const -{ - throw std::string ("unimplemented Att::reserved"); - return false; + std::stringstream s; + s << value; + mValue = s.str (); } //////////////////////////////////////////////////////////////////////////////// @@ -162,13 +177,14 @@ void Att::enquote (std::string& value) const } //////////////////////////////////////////////////////////////////////////////// -// Remove quotes. +// Remove quotes. Instead of being picky, just remove them all. There should +// be none within the value, and this will correct for one possible corruption +// that hand-editing the pending.data file could cause. void Att::dequote (std::string& value) const { - if (value.length () > 2 && - value[0] == '"' && - value[value.length () - 1] == '"') - value = value.substr (1, value.length () - 2); + std::string::size_type quote; + while ((quote = value.find ('"')) != std::string::npos) + value.replace (quote, 1, ""); } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/Att.h b/src/Att.h index c7ffa5579..c29312e80 100644 --- a/src/Att.h +++ b/src/Att.h @@ -36,6 +36,7 @@ class Att public: Att (); // Default constructor Att (const std::string&, const std::string&); // Simple constructor + Att (const std::string&, int); // Simple constructor Att (const Att&); // Copy constructor Att& operator= (const Att&); // Assignment operator ~Att (); // Destructor @@ -44,6 +45,7 @@ public: std::string composeF4 () const; void addMod (const std::string&); + // TODO Need method to access mods. std::string name () const; void name (const std::string&); @@ -54,10 +56,6 @@ public: int value_int () const; void value_int (int); - bool filter () const; - bool required () const; - bool reserved () const; - private: void enquote (std::string&) const; void dequote (std::string&) const; diff --git a/src/sandbox/TDB.cpp b/src/sandbox/TDB.cpp index 903af0b3c..3bca2e2f5 100644 --- a/src/sandbox/TDB.cpp +++ b/src/sandbox/TDB.cpp @@ -25,6 +25,7 @@ // //////////////////////////////////////////////////////////////////////////////// +#include #include #include #include "text.h" @@ -144,18 +145,23 @@ void TDB::unlock () } //////////////////////////////////////////////////////////////////////////////// -// TODO Returns number of filtered tasks. +// Returns number of filtered tasks. int TDB::load (std::vector & tasks, Filter& filter) { char line[T_LINE_MAX]; foreach (location, mLocations) { + + + + std::cout << "# location: " << location->first << std::endl; while (fgets (line, T_LINE_MAX, location->second)) { int length = ::strlen (line); if (length > 1) { line[length - 1] = '\0'; // Kill \n + std::cout << "# line: " << line << std::endl; T task (line); diff --git a/src/sandbox/TDB.h b/src/sandbox/TDB.h index 8a9461fb6..5b09168ca 100644 --- a/src/sandbox/TDB.h +++ b/src/sandbox/TDB.h @@ -67,7 +67,7 @@ private: bool mLock; bool mAllOpenAndLocked; - // TODO Need cache of raw file contents. + // TODO Need cache of raw file contents to preserve comments. }; #endif diff --git a/src/tests/.gitignore b/src/tests/.gitignore index e6e519ed2..d82085aed 100644 --- a/src/tests/.gitignore +++ b/src/tests/.gitignore @@ -7,3 +7,6 @@ text.t autocomplete.t parse.t seq.t +att.t +mod.t +record.t diff --git a/src/tests/Makefile b/src/tests/Makefile index 4a32b3b1d..52b29fee6 100644 --- a/src/tests/Makefile +++ b/src/tests/Makefile @@ -1,9 +1,9 @@ -PROJECT = t.t tdb.t date.t duration.t t.benchmark.t text.t autocomplete.t \ - parse.t seq.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 record.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 +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 all: $(PROJECT) @@ -46,3 +46,12 @@ parse.t: parse.t.o $(OBJECTS) test.o seq.t: seq.t.o $(OBJECTS) test.o g++ seq.t.o $(OBJECTS) test.o $(LFLAGS) -o seq.t +record.t: record.t.o $(OBJECTS) test.o + g++ record.t.o $(OBJECTS) test.o $(LFLAGS) -o record.t + +mod.t: mod.t.o $(OBJECTS) test.o + g++ mod.t.o $(OBJECTS) test.o $(LFLAGS) -o mod.t + +att.t: att.t.o $(OBJECTS) test.o + g++ att.t.o $(OBJECTS) test.o $(LFLAGS) -o att.t + diff --git a/src/tests/att.t.cpp b/src/tests/att.t.cpp new file mode 100644 index 000000000..c0c1bf2d0 --- /dev/null +++ b/src/tests/att.t.cpp @@ -0,0 +1,126 @@ +//////////////////////////////////////////////////////////////////////////////// +// task - a command line task list manager. +// +// Copyright 2006 - 2009, Paul Beckingham. +// All rights reserved. +// +// This program is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free Software +// Foundation; either version 2 of the License, or (at your option) any later +// version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +// details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the +// +// Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, +// Boston, MA +// 02110-1301 +// USA +// +//////////////////////////////////////////////////////////////////////////////// +#include +#include + +//////////////////////////////////////////////////////////////////////////////// +int main (int argc, char** argv) +{ + UnitTest t (31); + + Att a1 ("name", "value"); + t.is (a1.name (), "name", "Att::Att (name, value), Att.name"); + t.is (a1.value (), "value", "Att::Att (name, value), Att.value"); + + Att a2; + a2.name ("name"); + a2.value ("value"); + t.is (a2.name (), "name", "Att::Att (), Att.name"); + t.is (a2.value (), "value", "Att::Att (), Att.value"); + + Att a3 (a2); + t.is (a3.name (), "name", "Att::Att (Att), Att.name"); + t.is (a3.value (), "value", "Att::Att (Att), Att.value"); + + Att a4; + a4 = a2; + t.is (a4.name (), "name", "Att::Att (), Att.operator=, Att.name"); + t.is (a4.value (), "value", "Att::Att (), Att.operator=, Att.value"); + + Att a5 ("name", "value"); + t.is (a5.composeF4 (), "name:\"value\"", "Att::composeF4 simple"); + a5.value ("\""); + t.is (a5.composeF4 (), "name:\""\"", "Att::composeF4 encoded \""); + a5.value ("\t\",[]:"); + t.is (a5.composeF4 (), "name:\"&tab;",&open;&close;:\"", "Att::composeF4 fully encoded \\t\",[]:"); + + Att a6 ("name", 6); + t.is (a6.value_int (), 6, "Att::value_int get"); + a6.value_int (7); + t.is (a6.value_int (), 7, "Att::value_int set/get"); + t.is (a6.value (), "7", "Att::value 7"); + + // TODO Att::addMod + + // Att::parse + Att a7; + a7.parse (""); + t.is (a7.composeF4 (), "", "Att::composeF4 ()"); + + a7.parse ("name:value"); + t.is (a7.composeF4 (), "name:\"value\"", "Att::composeF4 (name:value)"); + + a7.parse ("name:\"value\""); + t.is (a7.composeF4 (), "name:\"value\"", "Att::composeF4 (name:\"value\")"); + + a7.parse ("name:\"one two\""); + t.is (a7.composeF4 (), "name:\"one two\"", "Att::composeF4 (name:\"one two\")"); + + a7.parse ("name:\""\""); + t.is (a7.composeF4 (), "name:\""\"", "Att::composeF4 (name:\""\")"); + + a7.parse ("name:\"&tab;",&open;&close;:\""); + t.is (a7.composeF4 (), "name:\"&tab;",&open;&close;:\"", + "Att::composeF4 (name:\"&tab;",&open;&close;:\")"); + + a7.parse ("total gibberish"); + t.is (a7.composeF4 (), "", "Att::composeF4 (total gibberish)"); + + a7.parse ("malformed"); + t.is (a7.composeF4 (), "", "Att::composeF4 (malformed)"); + + a7.parse (":malformed"); + t.is (a7.composeF4 (), "", "Att::composeF4 (:malformed)"); + + a7.parse (":\"\""); + t.is (a7.composeF4 (), "", "Att::composeF4 (:\"\")"); + + a7.parse (":\""); + t.is (a7.composeF4 (), "", "Att::composeF4 (:\")"); + + a7.parse ("name:"); + t.is (a7.composeF4 (), "", "Att::composeF4 (name:)"); + + a7.parse ("name:\"value"); + t.is (a7.composeF4 (), "name:\"value\"", "Att::composeF4 (name:\"value)"); + + a7.parse ("name:value\""); + t.is (a7.composeF4 (), "name:\"value\"", "Att::composeF4 (name:value\")"); + + a7.parse ("name:val\"ue"); + t.is (a7.composeF4 (), "name:\"value\"", "Att::composeF4 (name:val\"ue)"); + + a7.parse ("name:\"\"va\"\"\"\"\"lu\"\"\"e\"\""); + t.is (a7.composeF4 (), "name:\"value\"", "Att::composeF4 (name:\"\"va\"\"\"\"\"lu\"\"\"e\"\")"); + + a7.parse ("name\""); + t.is (a7.composeF4 (), "", "Att::composeF4 (name\")"); + + return 0; +} + +////////////////////////////////////////////////////////////////////////////////