diff --git a/src/Color.cpp b/src/Color.cpp index 771f60ff4..bac00a149 100644 --- a/src/Color.cpp +++ b/src/Color.cpp @@ -25,13 +25,14 @@ //////////////////////////////////////////////////////////////////////////////// #include +#include #include #include #include #include #include #include -#include +#include #include #include @@ -112,7 +113,7 @@ Color::Color (const std::string& spec) std::string word; for (auto& it : words) { - word = lowerCase (trim (it)); + word = Lexer::lowerCase (trim (it)); if (word == "bold") fg_value |= _COLOR_BOLD; else if (word == "bright") bg_value |= _COLOR_BRIGHT; diff --git a/src/Config.cpp b/src/Config.cpp index 1770e0d8f..94581feaa 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -25,6 +25,7 @@ //////////////////////////////////////////////////////////////////////////////// #include +#include #include #include #include @@ -37,7 +38,7 @@ #include #include #include -#include +#include #include #include #include @@ -587,7 +588,7 @@ bool Config::getBoolean (const std::string& key) { if ((*this).find (key) != (*this).end ()) { - std::string value = lowerCase ((*this)[key]); + std::string value = Lexer::lowerCase ((*this)[key]); if (value == "t" || // TODO Deprecate value == "true" || value == "1" || diff --git a/src/Dates.cpp b/src/Dates.cpp index 8c7f17ca6..c5f21ab6c 100644 --- a/src/Dates.cpp +++ b/src/Dates.cpp @@ -387,12 +387,12 @@ bool namedDates (const std::string& name, Variant& value) if (Lexer::isDigit (name[1])) { number = strtol (name.substr (0, 2).c_str (), NULL, 10); - ordinal = lowerCase (name.substr (2)); + ordinal = Lexer::lowerCase (name.substr (2)); } else { number = strtol (name.substr (0, 1).c_str (), NULL, 10); - ordinal = lowerCase (name.substr (1)); + ordinal = Lexer::lowerCase (name.substr (1)); } // Sanity check. diff --git a/src/ISO8601.cpp b/src/ISO8601.cpp index 4b21eed52..1749568d8 100644 --- a/src/ISO8601.cpp +++ b/src/ISO8601.cpp @@ -514,7 +514,7 @@ bool ISO8601d::parse_formatted (Nibbler& n, const std::string& format) std::string dayName; if (n.getUntil (format[f + 1], dayName)) { - wday = ISO8601d::dayOfWeek (lowerCase (dayName)); + wday = ISO8601d::dayOfWeek (Lexer::lowerCase (dayName)); if (wday == -1) { n.restore (); @@ -543,7 +543,7 @@ bool ISO8601d::parse_formatted (Nibbler& n, const std::string& format) std::string monthName; if (n.getUntil (format[f + 1], monthName)) { - month = ISO8601d::monthOfYear (lowerCase (monthName)); + month = ISO8601d::monthOfYear (Lexer::lowerCase (monthName)); if (month == -1) { n.restore (); @@ -1265,7 +1265,7 @@ std::string ISO8601d::monthName (int month) assert (month > 0); assert (month <= 12); - return ucFirst (months[month - 1]); + return Lexer::ucFirst (months[month - 1]); } //////////////////////////////////////////////////////////////////////////////// @@ -1283,7 +1283,7 @@ std::string ISO8601d::dayName (int dow) STRING_DATE_SATURDAY, }; - return ucFirst (days[dow]); + return Lexer::ucFirst (days[dow]); } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/Lexer.cpp b/src/Lexer.cpp index ddcb884ff..3ef152ec7 100644 --- a/src/Lexer.cpp +++ b/src/Lexer.cpp @@ -412,6 +412,100 @@ std::string::size_type Lexer::commonLength ( return l; } +//////////////////////////////////////////////////////////////////////////////// +std::string Lexer::commify (const std::string& data) +{ + // First scan for decimal point and end of digits. + int decimalPoint = -1; + int end = -1; + + int i; + for (int i = 0; i < (int) data.length (); ++i) + { + if (Lexer::isDigit (data[i])) + end = i; + + if (data[i] == '.') + decimalPoint = i; + } + + std::string result; + if (decimalPoint != -1) + { + // In reverse order, transfer all digits up to, and including the decimal + // point. + for (i = (int) data.length () - 1; i >= decimalPoint; --i) + result += data[i]; + + int consecutiveDigits = 0; + for (; i >= 0; --i) + { + if (Lexer::isDigit (data[i])) + { + result += data[i]; + + if (++consecutiveDigits == 3 && i && Lexer::isDigit (data[i - 1])) + { + result += ','; + consecutiveDigits = 0; + } + } + else + result += data[i]; + } + } + else + { + // In reverse order, transfer all digits up to, but not including the last + // digit. + for (i = (int) data.length () - 1; i > end; --i) + result += data[i]; + + int consecutiveDigits = 0; + for (; i >= 0; --i) + { + if (Lexer::isDigit (data[i])) + { + result += data[i]; + + if (++consecutiveDigits == 3 && i && Lexer::isDigit (data[i - 1])) + { + result += ','; + consecutiveDigits = 0; + } + } + else + result += data[i]; + } + } + + // reverse result into data. + std::string done; + for (int i = (int) result.length () - 1; i >= 0; --i) + done += result[i]; + + return done; +} + +//////////////////////////////////////////////////////////////////////////////// +std::string Lexer::lowerCase (const std::string& input) +{ + std::string output = input; + std::transform (output.begin (), output.end (), output.begin (), tolower); + return output; +} + +//////////////////////////////////////////////////////////////////////////////// +std::string Lexer::ucFirst (const std::string& input) +{ + std::string output = input; + + if (output.length () > 0) + output[0] = toupper (output[0]); + + return output; +} + //////////////////////////////////////////////////////////////////////////////// // Lexer::Type::string // '|" diff --git a/src/Lexer.h b/src/Lexer.h index 9aa510596..f31236ca7 100644 --- a/src/Lexer.h +++ b/src/Lexer.h @@ -87,6 +87,9 @@ public: static int hexToInt (int, int, int, int); static std::string::size_type commonLength (const std::string&, const std::string&); static std::string::size_type commonLength (const std::string&, std::string::size_type, const std::string&, std::string::size_type); + static std::string commify (const std::string&); + static std::string lowerCase (const std::string&); + static std::string ucFirst (const std::string&); // Stream Classifiers. bool isEOS () const; diff --git a/src/commands/CmdCalendar.cpp b/src/commands/CmdCalendar.cpp index 81fbb8bc2..e05102f05 100644 --- a/src/commands/CmdCalendar.cpp +++ b/src/commands/CmdCalendar.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -98,7 +99,7 @@ int CmdCalendar::execute (std::string& output) // Set up a vector of months, for autoComplete. std::vector monthNames; for (int i = 1; i <= 12; ++i) - monthNames.push_back (lowerCase (ISO8601d::monthName (i))); + monthNames.push_back (Lexer::lowerCase (ISO8601d::monthName (i))); // For autoComplete results. std::vector matches; @@ -113,15 +114,15 @@ int CmdCalendar::execute (std::string& output) for (auto& arg : words) { // Some version of "calendar". - if (autoComplete (lowerCase (arg), commandNames, matches, context.config.getInteger ("abbreviation.minimum")) == 1) + if (autoComplete (Lexer::lowerCase (arg), commandNames, matches, context.config.getInteger ("abbreviation.minimum")) == 1) continue; // "due". - else if (autoComplete (lowerCase (arg), keywordNames, matches, context.config.getInteger ("abbreviation.minimum")) == 1) + else if (autoComplete (Lexer::lowerCase (arg), keywordNames, matches, context.config.getInteger ("abbreviation.minimum")) == 1) getpendingdate = true; // "y". - else if (lowerCase (arg) == "y") + else if (Lexer::lowerCase (arg) == "y") argWholeYear = true; // YYYY. @@ -137,7 +138,7 @@ int CmdCalendar::execute (std::string& output) } // "January" etc. - else if (autoComplete (lowerCase (arg), monthNames, matches, context.config.getInteger ("abbreviation.minimum")) == 1) + else if (autoComplete (Lexer::lowerCase (arg), monthNames, matches, context.config.getInteger ("abbreviation.minimum")) == 1) { argMonth = ISO8601d::monthOfYear (matches[0]); if (argMonth == -1) diff --git a/src/commands/CmdEdit.cpp b/src/commands/CmdEdit.cpp index 7cb3b7109..91ef87805 100644 --- a/src/commands/CmdEdit.cpp +++ b/src/commands/CmdEdit.cpp @@ -25,6 +25,7 @@ //////////////////////////////////////////////////////////////////////////////// #include +#include #include #include #include @@ -33,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -40,7 +42,6 @@ #include #include #include -#include #include extern Context context; @@ -213,12 +214,12 @@ std::string CmdEdit::formatTask (Task task, const std::string& dateformat) before << "# " << STRING_EDIT_TABLE_HEADER_1 << "\n" << "# " << STRING_EDIT_TABLE_HEADER_2 << "\n" - << "# ID: " << task.id << "\n" - << "# UUID: " << task.get ("uuid") << "\n" - << "# Status: " << ucFirst (Task::statusToText (task.getStatus ())) << "\n" // L10N safe ucFirst. - << "# Mask: " << task.get ("mask") << "\n" - << "# iMask: " << task.get ("imask") << "\n" - << " Project: " << task.get ("project") << "\n"; + << "# ID: " << task.id << "\n" + << "# UUID: " << task.get ("uuid") << "\n" + << "# Status: " << Lexer::ucFirst (Task::statusToText (task.getStatus ())) << "\n" + << "# Mask: " << task.get ("mask") << "\n" + << "# iMask: " << task.get ("imask") << "\n" + << " Project: " << task.get ("project") << "\n"; std::vector tags; task.getTags (tags); diff --git a/src/commands/CmdInfo.cpp b/src/commands/CmdInfo.cpp index 1bf58f70a..a284b0efd 100644 --- a/src/commands/CmdInfo.cpp +++ b/src/commands/CmdInfo.cpp @@ -119,7 +119,7 @@ int CmdInfo::execute (std::string& output) view.set (row, 0, STRING_COLUMN_LABEL_ID); view.set (row, 1, (task.id ? format (task.id) : "-")); - std::string status = ucFirst (Task::statusToText (task.getStatus ())); // L10N safe ucFirst. + std::string status = Lexer::ucFirst (Task::statusToText (task.getStatus ())); // description Color c; diff --git a/src/feedback.cpp b/src/feedback.cpp index 45ff910c8..9e2862825 100644 --- a/src/feedback.cpp +++ b/src/feedback.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -64,7 +65,7 @@ std::string taskDifferences (const Task& before, const Task& after) std::stringstream out; for (auto& name : beforeOnly) out << " - " - << format (STRING_FEEDBACK_DELETED, ucFirst (name)) + << format (STRING_FEEDBACK_DELETED, Lexer::ucFirst (name)) << "\n"; for (auto& name : afterOnly) @@ -83,7 +84,7 @@ std::string taskDifferences (const Task& before, const Task& after) else out << " - " << format (STRING_FEEDBACK_ATT_SET, - ucFirst (name), + Lexer::ucFirst (name), renderAttribute (name, after.get (name))) << "\n"; } @@ -116,7 +117,7 @@ std::string taskDifferences (const Task& before, const Task& after) else out << " - " << format (STRING_FEEDBACK_ATT_MOD, - ucFirst (name), + Lexer::ucFirst (name), renderAttribute (name, before.get (name)), renderAttribute (name, after.get (name))) << "\n"; @@ -175,13 +176,13 @@ std::string taskInfoDifferences ( } else if (name == "start") { - out << format (STRING_FEEDBACK_ATT_DEL_DUR, ucFirst (name), + out << format (STRING_FEEDBACK_ATT_DEL_DUR, Lexer::ucFirst (name), ISO8601p (current_timestamp - last_timestamp).format ()) << "\n"; } else { - out << format (STRING_FEEDBACK_ATT_DEL, ucFirst (name)) + out << format (STRING_FEEDBACK_ATT_DEL, Lexer::ucFirst (name)) << "\n"; } } @@ -209,7 +210,7 @@ std::string taskInfoDifferences ( last_timestamp = current_timestamp; out << format (STRING_FEEDBACK_ATT_WAS_SET, - ucFirst (name), + Lexer::ucFirst (name), renderAttribute (name, after.get (name), dateformat)) << "\n"; } @@ -244,7 +245,7 @@ std::string taskInfoDifferences ( } else out << format (STRING_FEEDBACK_ATT_WAS_MOD, - ucFirst (name), + Lexer::ucFirst (name), renderAttribute (name, before.get (name), dateformat), renderAttribute (name, after.get (name), dateformat)) << "\n"; diff --git a/src/text.cpp b/src/text.cpp index 6a21d3ee4..69489fa02 100644 --- a/src/text.cpp +++ b/src/text.cpp @@ -357,100 +357,6 @@ bool extractLine ( return true; } -//////////////////////////////////////////////////////////////////////////////// -std::string commify (const std::string& data) -{ - // First scan for decimal point and end of digits. - int decimalPoint = -1; - int end = -1; - - int i; - for (int i = 0; i < (int) data.length (); ++i) - { - if (Lexer::isDigit (data[i])) - end = i; - - if (data[i] == '.') - decimalPoint = i; - } - - std::string result; - if (decimalPoint != -1) - { - // In reverse order, transfer all digits up to, and including the decimal - // point. - for (i = (int) data.length () - 1; i >= decimalPoint; --i) - result += data[i]; - - int consecutiveDigits = 0; - for (; i >= 0; --i) - { - if (Lexer::isDigit (data[i])) - { - result += data[i]; - - if (++consecutiveDigits == 3 && i && Lexer::isDigit (data[i - 1])) - { - result += ','; - consecutiveDigits = 0; - } - } - else - result += data[i]; - } - } - else - { - // In reverse order, transfer all digits up to, but not including the last - // digit. - for (i = (int) data.length () - 1; i > end; --i) - result += data[i]; - - int consecutiveDigits = 0; - for (; i >= 0; --i) - { - if (Lexer::isDigit (data[i])) - { - result += data[i]; - - if (++consecutiveDigits == 3 && i && Lexer::isDigit (data[i - 1])) - { - result += ','; - consecutiveDigits = 0; - } - } - else - result += data[i]; - } - } - - // reverse result into data. - std::string done; - for (int i = (int) result.length () - 1; i >= 0; --i) - done += result[i]; - - return done; -} - -//////////////////////////////////////////////////////////////////////////////// -std::string lowerCase (const std::string& input) -{ - std::string output = input; - std::transform (output.begin (), output.end (), output.begin (), tolower); - return output; -} - -//////////////////////////////////////////////////////////////////////////////// -std::string ucFirst (const std::string& input) -{ - std::string output = input; - - if (output.length () > 0) - output[0] = toupper (output[0]); - - return output; -} - //////////////////////////////////////////////////////////////////////////////// const std::string str_replace ( std::string &str, diff --git a/src/text.h b/src/text.h index 56577329d..5dcd78de9 100644 --- a/src/text.h +++ b/src/text.h @@ -46,9 +46,6 @@ void split (std::vector&, const std::string&, const char); void split (std::vector&, const std::string&, const std::string&); void join (std::string&, const std::string&, const std::vector&); void join (std::string&, const std::string&, const std::vector&); -std::string commify (const std::string&); -std::string lowerCase (const std::string&); -std::string ucFirst (const std::string&); const std::string str_replace (std::string&, const std::string&, const std::string&); const std::string str_replace (const std::string&, const std::string&, const std::string&); const char* optionalBlankLine (); diff --git a/src/util.cpp b/src/util.cpp index a05dcc94e..d47c4b7a0 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -51,6 +51,7 @@ #include #include +#include #include #include #include @@ -89,7 +90,7 @@ bool confirm (const std::string& question) std::string answer {""}; std::getline (std::cin, answer); context.debug ("STDIN '" + answer + "'"); - answer = std::cin.eof () ? STRING_UTIL_CONFIRM_NO : lowerCase (trim (answer)); + answer = std::cin.eof () ? STRING_UTIL_CONFIRM_NO : Lexer::lowerCase (trim (answer)); autoComplete (answer, options, matches, 1); // Hard-coded 1. } @@ -129,7 +130,7 @@ int confirm4 (const std::string& question) std::string answer {""}; std::getline (std::cin, answer); context.debug ("STDIN '" + answer + "'"); - answer = std::cin.eof () ? STRING_UTIL_CONFIRM_QUIT : lowerCase (trim (answer)); + answer = std::cin.eof () ? STRING_UTIL_CONFIRM_QUIT : Lexer::lowerCase (trim (answer)); autoComplete (answer, options, matches, 1); // Hard-coded 1. } while (! std::cin.eof () && matches.size () != 1); @@ -159,7 +160,7 @@ std::string formatBytes (size_t bytes) else if (bytes >= 995) sprintf (formatted, "%.1f %s", (bytes / 1000.0), STRING_UTIL_KIBIBYTES); else sprintf (formatted, "%d %s", (int)bytes, STRING_UTIL_BYTES); - return commify (formatted); + return Lexer::commify (formatted); } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/lexer.t.cpp b/test/lexer.t.cpp index f480f36b8..9d32857df 100644 --- a/test/lexer.t.cpp +++ b/test/lexer.t.cpp @@ -37,7 +37,7 @@ Context context; //////////////////////////////////////////////////////////////////////////////// int main (int, char**) { - UnitTest t (1226); + UnitTest t (1253); std::vector > tokens; std::string token; @@ -551,6 +551,37 @@ int main (int, char**) t.is (Lexer::typeName (Lexer::Type::date), "date", "Lexer::typeName (Lexer::Type::date)"); t.is (Lexer::typeName (Lexer::Type::duration), "duration", "Lexer::typeName (Lexer::Type::duration)"); + // std::string Lexer::lowerCase (const std::string& input) + t.is (Lexer::lowerCase (""), "", "Lexer::lowerCase '' -> ''"); + t.is (Lexer::lowerCase ("pre01_:POST"), "pre01_:post", "Lexer::lowerCase 'pre01_:POST' -> 'pre01_:post'"); + + // std::string Lexer::commify (const std::string& data) + t.is (Lexer::commify (""), "", "Lexer::commify '' -> ''"); + t.is (Lexer::commify ("1"), "1", "Lexer::commify '1' -> '1'"); + t.is (Lexer::commify ("12"), "12", "Lexer::commify '12' -> '12'"); + t.is (Lexer::commify ("123"), "123", "Lexer::commify '123' -> '123'"); + t.is (Lexer::commify ("1234"), "1,234", "Lexer::commify '1234' -> '1,234'"); + t.is (Lexer::commify ("12345"), "12,345", "Lexer::commify '12345' -> '12,345'"); + t.is (Lexer::commify ("123456"), "123,456", "Lexer::commify '123456' -> '123,456'"); + t.is (Lexer::commify ("1234567"), "1,234,567", "Lexer::commify '1234567' -> '1,234,567'"); + t.is (Lexer::commify ("12345678"), "12,345,678", "Lexer::commify '12345678' -> '12,345,678'"); + t.is (Lexer::commify ("123456789"), "123,456,789", "Lexer::commify '123456789' -> '123,456,789'"); + t.is (Lexer::commify ("1234567890"), "1,234,567,890", "Lexer::commify '1234567890' -> '1,234,567,890'"); + t.is (Lexer::commify ("1.0"), "1.0", "Lexer::commify '1.0' -> '1.0'"); + t.is (Lexer::commify ("12.0"), "12.0", "Lexer::commify '12.0' -> '12.0'"); + t.is (Lexer::commify ("123.0"), "123.0", "Lexer::commify '123.0' -> '123.0'"); + t.is (Lexer::commify ("1234.0"), "1,234.0", "Lexer::commify '1234.0' -> '1,234.0'"); + t.is (Lexer::commify ("12345.0"), "12,345.0", "Lexer::commify '12345.0' -> '12,345.0'"); + t.is (Lexer::commify ("123456.0"), "123,456.0", "Lexer::commify '123456.0' -> '123,456.0'"); + t.is (Lexer::commify ("1234567.0"), "1,234,567.0", "Lexer::commify '1234567.0' -> '1,234,567.0'"); + t.is (Lexer::commify ("12345678.0"), "12,345,678.0", "Lexer::commify '12345678.0' -> '12,345,678.0'"); + t.is (Lexer::commify ("123456789.0"), "123,456,789.0", "Lexer::commify '123456789.0' -> '123,456,789.0'"); + t.is (Lexer::commify ("1234567890.0"), "1,234,567,890.0", "Lexer::commify '1234567890.0' -> '1,234,567,890.0'"); + t.is (Lexer::commify ("pre"), "pre", "Lexer::commify 'pre' -> 'pre'"); + t.is (Lexer::commify ("pre1234"), "pre1,234", "Lexer::commify 'pre1234' -> 'pre1,234'"); + t.is (Lexer::commify ("1234post"), "1,234post", "Lexer::commify '1234post' -> '1,234post'"); + t.is (Lexer::commify ("pre1234post"), "pre1,234post", "Lexer::commify 'pre1234post' -> 'pre1,234post'"); + return 0; } diff --git a/test/text.t.cpp b/test/text.t.cpp index cd80d32ec..7116ae835 100644 --- a/test/text.t.cpp +++ b/test/text.t.cpp @@ -37,7 +37,7 @@ Context context; //////////////////////////////////////////////////////////////////////////////// int main (int, char**) { - UnitTest t (225); + UnitTest t (198); // Ensure environment has no influence. unsetenv ("TASKDATA"); @@ -258,37 +258,6 @@ int main (int, char**) t.is (longestLine ("one\ntwo three four"), 14, "longestLine (one\\ntwo three four) --> 14"); t.is (longestLine ("one\ntwo\nthree\nfour"), 5, "longestLine (one\\ntwo\\nthree\\nfour) --> 5"); - // std::string commify (const std::string& data) - t.is (commify (""), "", "commify '' -> ''"); - t.is (commify ("1"), "1", "commify '1' -> '1'"); - t.is (commify ("12"), "12", "commify '12' -> '12'"); - t.is (commify ("123"), "123", "commify '123' -> '123'"); - t.is (commify ("1234"), "1,234", "commify '1234' -> '1,234'"); - t.is (commify ("12345"), "12,345", "commify '12345' -> '12,345'"); - t.is (commify ("123456"), "123,456", "commify '123456' -> '123,456'"); - t.is (commify ("1234567"), "1,234,567", "commify '1234567' -> '1,234,567'"); - t.is (commify ("12345678"), "12,345,678", "commify '12345678' -> '12,345,678'"); - t.is (commify ("123456789"), "123,456,789", "commify '123456789' -> '123,456,789'"); - t.is (commify ("1234567890"), "1,234,567,890", "commify '1234567890' -> '1,234,567,890'"); - t.is (commify ("1.0"), "1.0", "commify '1.0' -> '1.0'"); - t.is (commify ("12.0"), "12.0", "commify '12.0' -> '12.0'"); - t.is (commify ("123.0"), "123.0", "commify '123.0' -> '123.0'"); - t.is (commify ("1234.0"), "1,234.0", "commify '1234.0' -> '1,234.0'"); - t.is (commify ("12345.0"), "12,345.0", "commify '12345.0' -> '12,345.0'"); - t.is (commify ("123456.0"), "123,456.0", "commify '123456.0' -> '123,456.0'"); - t.is (commify ("1234567.0"), "1,234,567.0", "commify '1234567.0' -> '1,234,567.0'"); - t.is (commify ("12345678.0"), "12,345,678.0", "commify '12345678.0' -> '12,345,678.0'"); - t.is (commify ("123456789.0"), "123,456,789.0", "commify '123456789.0' -> '123,456,789.0'"); - t.is (commify ("1234567890.0"), "1,234,567,890.0", "commify '1234567890.0' -> '1,234,567,890.0'"); - t.is (commify ("pre"), "pre", "commify 'pre' -> 'pre'"); - t.is (commify ("pre1234"), "pre1,234", "commify 'pre1234' -> 'pre1,234'"); - t.is (commify ("1234post"), "1,234post", "commify '1234post' -> '1,234post'"); - t.is (commify ("pre1234post"), "pre1,234post", "commify 'pre1234post' -> 'pre1,234post'"); - - // std::string lowerCase (const std::string& input) - t.is (lowerCase (""), "", "lowerCase '' -> ''"); - t.is (lowerCase ("pre01_:POST"), "pre01_:post", "lowerCase 'pre01_:POST' -> 'pre01_:post'"); - // bool nontrivial (const std::string&); t.notok (nontrivial (""), "nontrivial '' -> false"); t.notok (nontrivial (" "), "nontrivial ' ' -> false");