From 9cd1b96e1f947e609236b2c0460c828f04a6b13e Mon Sep 17 00:00:00 2001 From: "Dustin J. Mitchell" Date: Wed, 26 Jun 2024 01:33:46 -0400 Subject: [PATCH] Remove support for the F4 format (#3494) This was only still used in tests. --- src/Task.cpp | 106 +-------------------------------------------- src/Task.h | 1 - test/t.test.cpp | 77 ++------------------------------ test/view.test.cpp | 54 ++++++++++++----------- 4 files changed, 34 insertions(+), 204 deletions(-) diff --git a/src/Task.cpp b/src/Task.cpp index cb9626b41..36d690e3d 100644 --- a/src/Task.cpp +++ b/src/Task.cpp @@ -622,75 +622,10 @@ bool Task::is_waiting () const } //////////////////////////////////////////////////////////////////////////////// -// Attempt an FF4 parse first, using Task::parse, and in the event of an error -// try a JSON parse, otherwise a legacy parse (currently no legacy formats are -// supported). -// -// Note that FF1, FF2 and FF3 are no longer supported. -// -// start --> [ --> Att --> ] --> end -// ^ | -// +-------+ -// +// Try a JSON parse. void Task::parse (const std::string& input) { - try - { - // File format version 4, from 2009-5-16 - now, v1.7.1+ - // This is the parse format tried first, because it is most used. - data.clear (); - - if (input[0] == '[') - { - // Not using Pig to parse here (which would be idiomatic), because we - // don't need to differentiate betwen utf-8 and normal characters. - // Pig's scanning the string can be expensive. - auto ending_bracket = input.find_last_of (']'); - if (ending_bracket != std::string::npos) - { - std::string line = input.substr(1, ending_bracket); - - if (line.length () == 0) - throw std::string ("Empty record in input."); - - Pig attLine (line); - std::string name; - std::string value; - while (!attLine.eos ()) - { - if (attLine.getUntilAscii (':', name) && - attLine.skip (':') && - attLine.getQuoted ('"', value)) - { -#ifdef PRODUCT_TASKWARRIOR - legacyAttributeMap (name); -#endif - - if (isAnnotationAttr (name)) - ++annotation_count; - - data[name] = decode (json::decode (value)); - } - - attLine.skip (' '); - } - - std::string remainder; - attLine.getRemainder (remainder); - if (remainder.length ()) - throw std::string ("Unrecognized characters at end of line."); - } - } - else if (input[0] == '{') - parseJSON (input); - else - throw std::string ("Record not recognized as format 4."); - } - - catch (const std::string&) - { - parseLegacy (input); - } + parseJSON (input); // for compatibility, include all tags in `tags` as `tag_..` attributes if (data.find ("tags") != data.end ()) { @@ -965,43 +900,6 @@ void Task::parseLegacy (const std::string& line) recalc_urgency = true; } -//////////////////////////////////////////////////////////////////////////////// -// The format is: -// -// [ : ... ] -// -std::string Task::composeF4 () const -{ - std::string ff4 = "["; - - bool first = true; - for (const auto& it : data) - { - // Orphans have no type, treat as string. - std::string type = Task::attributes[it.first]; - if (type == "") - type = "string"; - - // If there is a value. - if (it.second != "") - { - ff4 += (first ? "" : " "); - ff4 += it.first; - ff4 += ":\""; - if (type == "string") - ff4 += encode (json::encode (it.second)); - else - ff4 += it.second; - ff4 += '"'; - - first = false; - } - } - - ff4 += ']'; - return ff4; -} - //////////////////////////////////////////////////////////////////////////////// std::string Task::composeJSON (bool decorate /*= false*/) const { diff --git a/src/Task.h b/src/Task.h index eb7b2b71f..3f4e16e16 100644 --- a/src/Task.h +++ b/src/Task.h @@ -69,7 +69,6 @@ public: Task (tc::Task); void parse (const std::string&); - std::string composeF4 () const; std::string composeJSON (bool decorate = false) const; // Status values. diff --git a/test/t.test.cpp b/test/t.test.cpp index a6ea56268..63739c6da 100644 --- a/test/t.test.cpp +++ b/test/t.test.cpp @@ -32,7 +32,7 @@ //////////////////////////////////////////////////////////////////////////////// int main (int, char**) { - UnitTest test (49); + UnitTest test (48); Context context; Context::setContext(&context); @@ -50,77 +50,6 @@ int main (int, char**) test.is (Task::statusToText (Task::deleted), "deleted", "statusToText deleted"); test.is (Task::statusToText (Task::recurring), "recurring", "statusToText recurring"); - // Round-trip testing. - Task t3; - t3.set ("name", "value"); - std::string before = t3.composeF4 (); - t3.parse (before); - std::string after = t3.composeF4 (); - t3.parse (after); - after = t3.composeF4 (); - t3.parse (after); - after = t3.composeF4 (); - test.is (before, after, "Task::composeF4 -> parse round trip 4 iterations"); - - // Legacy Format 1 (no longer supported) - // [tags] [attributes] description\n - // X [tags] [attributes] description\n - std::string sample = "[tag1 tag2] [att1:value1 att2:value2] Description"; - sample = "X " - "[one two] " - "[att1:value1 att2:value2] " - "Description"; - bool good = true; - try { Task ff1 (sample); } catch (...) { good = false; } - test.notok (good, "Support for ff1 removed"); - - // Legacy Format 2 (no longer supported) - // uuid status [tags] [attributes] description\n - sample = "00000000-0000-0000-0000-000000000000 " - "- " - "[tag1 tag2] " - "[att1:value1 att2:value2] " - "Description"; - good = true; - try { Task ff2 (sample); } catch (...) { good = false; } - test.notok (good, "Support for ff2 removed"); - - // Legacy Format 3 - // uuid status [tags] [attributes] [annotations] description\n - sample = "00000000-0000-0000-0000-000000000000 " - "- " - "[tag1 tag2] " - "[att1:value1 att2:value2] " - "[123:ann1 456:ann2] Description"; - good = true; - try { Task ff3 (sample); } catch (...) { good = false; } - test.notok (good, "Support for ff3 removed"); - - // Current Format 4 - // [name:"value" ...]\n - sample = "[" - "uuid:\"00000000-0000-0000-0000-000000000000\" " - "status:\"pending\" " - "tags:\"tag1,tag2\" " - "att1:\"value1\" " - "att2:\"value2\" " - "description:\"Description\"" - "]"; - Task ff4 (sample); - std::string value = ff4.get ("uuid"); - test.is (value, "00000000-0000-0000-0000-000000000000", "ff4 uuid"); - value = ff4.get ("status"); - test.is (value, "pending", "ff4 status"); - test.ok (ff4.hasTag ("tag1"), "ff4 tag1"); - test.ok (ff4.hasTag ("tag2"), "ff4 tag2"); - test.is (ff4.getTagCount (), 2, "ff4 # tags"); - value = ff4.get ("att1"); - test.is (value, "value1", "ff4 att1"); - value = ff4.get ("att2"); - test.is (value, "value2", "ff4 att2"); - value = ff4.get ("description"); - test.is (value, "Description", "ff4 description"); - /* TODO Task::composeCSV @@ -145,7 +74,7 @@ TODO Task::decode */ // Task::operator== - Task left ("[one:1 two:2 three:3]"); + Task left ("{\"one\":\"1\", \"two\":\"2\", \"three\":\"3\"}"); Task right (left); test.ok (left == right, "left == right -> true"); left.set ("one", "1.0"); @@ -188,7 +117,7 @@ TODO Task::decode Task::attributes["tags"] = "string"; Task::attributes["uuid"] = "string"; - good = true; + bool good = true; try {Task t4 ("{}");} catch (const std::string& e){test.diag (e); good = false;} test.ok (good, "Task::Task ('{}')"); diff --git a/test/view.test.cpp b/test/view.test.cpp index 7c0e4f500..c65045c5d 100644 --- a/test/view.test.cpp +++ b/test/view.test.cpp @@ -63,34 +63,38 @@ int main (int, char**) context.config.set ("indent.annotation", "2"); // Two sample tasks. - Task t1 ("[" - "status:\"pending\" " - "uuid:\"2a64f6e0-bf8e-430d-bf71-9ec3f0d9b661\" " - "description:\"This is the description text\" " - "project:\"Home\" " - "priority:\"H\" " - "annotation_1234567890:\"This is an annotation\" " - "start:\"1234567890\" " - "due:\"1234567890\" " - "tags:\"one,two\"" - "]"); + t.ok(true, "zero"); + Task t1 ("{" + "\"status\":\"pending\", " + "\"uuid\":\"2a64f6e0-bf8e-430d-bf71-9ec3f0d9b661\", " + "\"description\":\"This is the description text\", " + "\"project\":\"Home\", " + "\"priority\":\"H\", " + "\"annotation_1234567890\":\"This is an annotation\", " + "\"start\":\"1234567890\", " + "\"due\":\"1234567890\", " + "\"tags\":\"one,two\"" + "}"); t1.id = 1; - Task t2 ("[" - "status:\"pending\" " - "uuid:\"f30cb9c3-3fc0-483f-bfb2-3bf134f00694\" " - "description:\"This is the description text\" " - "project:\"Garden Care\" " - "recur:\"monthly\" " - "depends:\"2a64f6e0-bf8e-430d-bf71-9ec3f0d9b661\"" - "]"); + t.ok(true, "one"); + Task t2 ("{" + "\"status\":\"pending\", " + "\"uuid\":\"f30cb9c3-3fc0-483f-bfb2-3bf134f00694\", " + "\"description\":\"This is the description text\", " + "\"project\":\"Garden Care\", " + "\"recur\":\"monthly\", " + "\"depends\":\"2a64f6e0-bf8e-430d-bf71-9ec3f0d9b661\"" + "}"); t2.id = 11; - Task t3 ("[" - "status:\"pending\" " - "uuid:\"c44cb9c3-3fc0-483f-bfb2-3bf134f05554\" " - "description:\"Another description\" " - "project:\"Garden\" " - "]"); + t.ok(true, "two"); + Task t3 ("{" + "\"status\":\"pending\", " + "\"uuid\":\"c44cb9c3-3fc0-483f-bfb2-3bf134f05554\", " + "\"description\":\"Another description\", " + "\"project\":\"Garden\"" + "}"); t3.id = 8; + t.ok(true, "three"); std::vector data; data.push_back (t1);