mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-06-26 10:54:26 +02:00
Enhancement - T2 implementation
- Improved Att/Mod implementation. - Implemented more T2 methods.
This commit is contained in:
parent
f295fdf78f
commit
25450b4a7c
4 changed files with 254 additions and 15 deletions
|
@ -196,6 +196,12 @@ bool Att::evalMod (Att& other)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
bool Att::match (const Att& other)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// name : " value "
|
// name : " value "
|
||||||
std::string Att::composeF4 () const
|
std::string Att::composeF4 () const
|
||||||
|
|
|
@ -44,6 +44,7 @@ public:
|
||||||
bool parse (Nibbler&);
|
bool parse (Nibbler&);
|
||||||
bool validMod (const std::string&);
|
bool validMod (const std::string&);
|
||||||
bool evalMod (Att&);
|
bool evalMod (Att&);
|
||||||
|
bool match (const Att&);
|
||||||
std::string composeF4 () const;
|
std::string composeF4 () const;
|
||||||
|
|
||||||
void addMod (const std::string&);
|
void addMod (const std::string&);
|
||||||
|
|
245
src/T2.cpp
245
src/T2.cpp
|
@ -60,7 +60,8 @@ T2& T2::operator= (const T2& other)
|
||||||
throw std::string ("unimplemented T2::operator=");
|
throw std::string ("unimplemented T2::operator=");
|
||||||
if (this != &other)
|
if (this != &other)
|
||||||
{
|
{
|
||||||
mId = other.mId;
|
sequence = other.sequence;
|
||||||
|
subst = other.subst;
|
||||||
}
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -73,8 +74,177 @@ T2::~T2 ()
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Support FF2, FF3.
|
// Support FF2, FF3.
|
||||||
void T2::legacyParse (const std::string& input)
|
void T2::legacyParse (const std::string& line)
|
||||||
{
|
{
|
||||||
|
switch (determineVersion (line))
|
||||||
|
{
|
||||||
|
// File format version 1, from 2006.11.27 - 2007.12.31
|
||||||
|
case 1:
|
||||||
|
throw std::string ("Task no longer supports file format 1, originally used "
|
||||||
|
"between 27 November 2006 and 31 December 2007.");
|
||||||
|
break;
|
||||||
|
|
||||||
|
// File format version 2, from 2008.1.1 - 2009.3.23
|
||||||
|
case 2:
|
||||||
|
/*
|
||||||
|
{
|
||||||
|
if (line.length () > 46) // ^.{36} . \[\] \[\] \n
|
||||||
|
{
|
||||||
|
mUUID = line.substr (0, 36);
|
||||||
|
|
||||||
|
mStatus = line[37] == '+' ? completed
|
||||||
|
: line[37] == 'X' ? deleted
|
||||||
|
: line[37] == 'r' ? recurring
|
||||||
|
: pending;
|
||||||
|
|
||||||
|
size_t openTagBracket = line.find ("[");
|
||||||
|
size_t closeTagBracket = line.find ("]", openTagBracket);
|
||||||
|
if (openTagBracket != std::string::npos &&
|
||||||
|
closeTagBracket != std::string::npos)
|
||||||
|
{
|
||||||
|
size_t openAttrBracket = line.find ("[", closeTagBracket);
|
||||||
|
size_t closeAttrBracket = line.find ("]", openAttrBracket);
|
||||||
|
if (openAttrBracket != std::string::npos &&
|
||||||
|
closeAttrBracket != std::string::npos)
|
||||||
|
{
|
||||||
|
std::string tags = line.substr (
|
||||||
|
openTagBracket + 1, closeTagBracket - openTagBracket - 1);
|
||||||
|
std::vector <std::string> rawTags;
|
||||||
|
split (mTags, tags, ' ');
|
||||||
|
|
||||||
|
std::string attributes = line.substr (
|
||||||
|
openAttrBracket + 1, closeAttrBracket - openAttrBracket - 1);
|
||||||
|
std::vector <std::string> pairs;
|
||||||
|
split (pairs, attributes, ' ');
|
||||||
|
for (size_t i = 0; i < pairs.size (); ++i)
|
||||||
|
{
|
||||||
|
std::vector <std::string> pair;
|
||||||
|
split (pair, pairs[i], ':');
|
||||||
|
if (pair.size () == 2)
|
||||||
|
mAttributes[pair[0]] = pair[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
mDescription = line.substr (closeAttrBracket + 2, std::string::npos);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw std::string ("Missing attribute brackets");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw std::string ("Missing tag brackets");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw std::string ("Line too short");
|
||||||
|
|
||||||
|
mAnnotations.clear ();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
break;
|
||||||
|
|
||||||
|
// File format version 3, from 2009.3.23
|
||||||
|
case 3:
|
||||||
|
/*
|
||||||
|
{
|
||||||
|
if (line.length () > 49) // ^.{36} . \[\] \[\] \[\] \n
|
||||||
|
{
|
||||||
|
mUUID = line.substr (0, 36);
|
||||||
|
|
||||||
|
mStatus = line[37] == '+' ? completed
|
||||||
|
: line[37] == 'X' ? deleted
|
||||||
|
: line[37] == 'r' ? recurring
|
||||||
|
: pending;
|
||||||
|
|
||||||
|
size_t openTagBracket = line.find ("[");
|
||||||
|
size_t closeTagBracket = line.find ("]", openTagBracket);
|
||||||
|
if (openTagBracket != std::string::npos &&
|
||||||
|
closeTagBracket != std::string::npos)
|
||||||
|
{
|
||||||
|
size_t openAttrBracket = line.find ("[", closeTagBracket);
|
||||||
|
size_t closeAttrBracket = line.find ("]", openAttrBracket);
|
||||||
|
if (openAttrBracket != std::string::npos &&
|
||||||
|
closeAttrBracket != std::string::npos)
|
||||||
|
{
|
||||||
|
size_t openAnnoBracket = line.find ("[", closeAttrBracket);
|
||||||
|
size_t closeAnnoBracket = line.find ("]", openAnnoBracket);
|
||||||
|
if (openAnnoBracket != std::string::npos &&
|
||||||
|
closeAnnoBracket != std::string::npos)
|
||||||
|
{
|
||||||
|
std::string tags = line.substr (
|
||||||
|
openTagBracket + 1, closeTagBracket - openTagBracket - 1);
|
||||||
|
std::vector <std::string> rawTags;
|
||||||
|
split (mTags, tags, ' ');
|
||||||
|
|
||||||
|
std::string attributes = line.substr (
|
||||||
|
openAttrBracket + 1, closeAttrBracket - openAttrBracket - 1);
|
||||||
|
std::vector <std::string> pairs;
|
||||||
|
split (pairs, attributes, ' ');
|
||||||
|
|
||||||
|
for (size_t i = 0; i < pairs.size (); ++i)
|
||||||
|
{
|
||||||
|
std::vector <std::string> pair;
|
||||||
|
split (pair, pairs[i], ':');
|
||||||
|
if (pair.size () == 2)
|
||||||
|
mAttributes[pair[0]] = pair[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract and split the annotations, which are of the form:
|
||||||
|
// 1234:"..." 5678:"..."
|
||||||
|
std::string annotations = line.substr (
|
||||||
|
openAnnoBracket + 1, closeAnnoBracket - openAnnoBracket - 1);
|
||||||
|
pairs.clear ();
|
||||||
|
|
||||||
|
std::string::size_type start = 0;
|
||||||
|
std::string::size_type end = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
end = annotations.find ('"', start);
|
||||||
|
if (end != std::string::npos)
|
||||||
|
{
|
||||||
|
end = annotations.find ('"', end + 1);
|
||||||
|
|
||||||
|
if (start != std::string::npos &&
|
||||||
|
end != std::string::npos)
|
||||||
|
{
|
||||||
|
pairs.push_back (annotations.substr (start, end - start + 1));
|
||||||
|
start = end + 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (start != std::string::npos &&
|
||||||
|
end != std::string::npos);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < pairs.size (); ++i)
|
||||||
|
{
|
||||||
|
std::string pair = pairs[i];
|
||||||
|
std::string::size_type colon = pair.find (":");
|
||||||
|
if (colon != std::string::npos)
|
||||||
|
{
|
||||||
|
std::string name = pair.substr (0, colon);
|
||||||
|
std::string value = pair.substr (colon + 2, pair.length () - colon - 3);
|
||||||
|
mAnnotations[::atoi (name.c_str ())] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mDescription = line.substr (closeAnnoBracket + 2, std::string::npos);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw std::string ("Missing annotation brackets.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw std::string ("Missing attribute brackets.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw std::string ("Missing tag brackets.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw std::string ("Line too short.");
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw std::string ("Unrecognized task file format.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -130,3 +300,74 @@ bool T2::validate () const
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
int T2::determineVersion (const std::string& line)
|
||||||
|
{
|
||||||
|
// Version 2 looks like:
|
||||||
|
//
|
||||||
|
// uuid status [tags] [attributes] description\n
|
||||||
|
//
|
||||||
|
// Where uuid looks like:
|
||||||
|
//
|
||||||
|
// 27755d92-c5e9-4c21-bd8e-c3dd9e6d3cf7
|
||||||
|
//
|
||||||
|
// Scan for the hyphens in the uuid, the following space, and a valid status
|
||||||
|
// character.
|
||||||
|
if (line[8] == '-' &&
|
||||||
|
line[13] == '-' &&
|
||||||
|
line[18] == '-' &&
|
||||||
|
line[23] == '-' &&
|
||||||
|
line[36] == ' ' &&
|
||||||
|
(line[37] == '-' || line[37] == '+' || line[37] == 'X' || line[37] == 'r'))
|
||||||
|
{
|
||||||
|
// Version 3 looks like:
|
||||||
|
//
|
||||||
|
// uuid status [tags] [attributes] [annotations] description\n
|
||||||
|
//
|
||||||
|
// Scan for the number of [] pairs.
|
||||||
|
std::string::size_type tagAtts = line.find ("] [", 0);
|
||||||
|
std::string::size_type attsAnno = line.find ("] [", tagAtts + 1);
|
||||||
|
std::string::size_type annoDesc = line.find ("] ", attsAnno + 1);
|
||||||
|
if (tagAtts != std::string::npos &&
|
||||||
|
attsAnno != std::string::npos &&
|
||||||
|
annoDesc != std::string::npos)
|
||||||
|
return 3;
|
||||||
|
else
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Version 1 looks like:
|
||||||
|
//
|
||||||
|
// [tags] [attributes] description\n
|
||||||
|
// X [tags] [attributes] description\n
|
||||||
|
//
|
||||||
|
// Scan for the first character being either the bracket or X.
|
||||||
|
else if ((line[0] == '[' && line[line.length () - 1] != ']') ||
|
||||||
|
line.find ("X [") == 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
// Version 4 looks like:
|
||||||
|
//
|
||||||
|
// [name:"value" ...]
|
||||||
|
//
|
||||||
|
// Scan for [, ] and :".
|
||||||
|
if (line[0] == '[' &&
|
||||||
|
line[line.length () - 1] == ']' &&
|
||||||
|
line.find (":\"") != std::string::npos)
|
||||||
|
return 4;
|
||||||
|
|
||||||
|
// Version 5?
|
||||||
|
//
|
||||||
|
// Fortunately, with the hindsight that will come with version 5, the
|
||||||
|
// identifying characteristics of 1, 2, 3 and 4 may be modified such that if 5
|
||||||
|
// has a UUID followed by a status, then there is still a way to differentiate
|
||||||
|
// between 2, 3, 4 and 5.
|
||||||
|
//
|
||||||
|
// The danger is that a version 3 binary reads and misinterprets a version 4
|
||||||
|
// file. This is why it is a good idea to rely on an explicit version
|
||||||
|
// declaration rather than chance positioning.
|
||||||
|
|
||||||
|
// Zero means 'no idea'.
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
17
src/T2.h
17
src/T2.h
|
@ -51,19 +51,16 @@ public:
|
||||||
Subst subst;
|
Subst subst;
|
||||||
|
|
||||||
// Series of helper functions.
|
// Series of helper functions.
|
||||||
int getId () const { return mId; }
|
int id () const { return sequence.size () ? sequence[0] : 0; }
|
||||||
void setId (int id) { mId = id; sequence.push_back (id); }
|
void id (int anotherId) { sequence.push_back (anotherId); }
|
||||||
|
|
||||||
/*
|
/*
|
||||||
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; }
|
status getStatus () const { return mStatus; }
|
||||||
void setStatus (status s) { mStatus = s; }
|
void setStatus (status s) { mStatus = s; }
|
||||||
|
|
||||||
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
|
||||||
int getTagCount () const;
|
int getTagCount () const;
|
||||||
void getTags (std::vector<std::string>&) const;
|
void getTags (std::vector<std::string>&) const;
|
||||||
void addTag (const std::string&);
|
void addTag (const std::string&);
|
||||||
|
@ -79,15 +76,9 @@ public:
|
||||||
bool validate () const;
|
bool validate () const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*
|
|
||||||
int determineVersion (const std::string&);
|
int determineVersion (const std::string&);
|
||||||
*/
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*
|
|
||||||
status mStatus;
|
|
||||||
*/
|
|
||||||
int mId;
|
|
||||||
/*
|
/*
|
||||||
std::vector<std::string> mTags;
|
std::vector<std::string> mTags;
|
||||||
std::vector<std::string> mRemoveTags;
|
std::vector<std::string> mRemoveTags;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue