diff --git a/src/text.cpp b/src/text.cpp index fa329a8db..8367ab49e 100644 --- a/src/text.cpp +++ b/src/text.cpp @@ -43,6 +43,8 @@ extern Context context; static const char* newline = "\n"; static const char* noline = ""; +static void replace_positional (std::string&, const std::string&, const std::string&); + /////////////////////////////////////////////////////////////////////////////// void wrapText ( std::vector & lines, @@ -726,7 +728,7 @@ std::string cutOff (const std::string& str, std::string::size_type len) } //////////////////////////////////////////////////////////////////////////////// -std::string format (char value) +const std::string format (char value) { std::stringstream s; s << value; @@ -734,7 +736,7 @@ std::string format (char value) } //////////////////////////////////////////////////////////////////////////////// -std::string format (int value) +const std::string format (int value) { std::stringstream s; s << value; @@ -742,7 +744,7 @@ std::string format (int value) } //////////////////////////////////////////////////////////////////////////////// -std::string formatHex (int value) +const std::string formatHex (int value) { std::stringstream s; s.setf (std::ios::hex, std::ios::basefield); @@ -751,7 +753,7 @@ std::string formatHex (int value) } //////////////////////////////////////////////////////////////////////////////// -std::string format (float value, int width, int precision) +const std::string format (float value, int width, int precision) { std::stringstream s; s.width (width); @@ -761,7 +763,7 @@ std::string format (float value, int width, int precision) } //////////////////////////////////////////////////////////////////////////////// -std::string format (double value, int width, int precision) +const std::string format (double value, int width, int precision) { std::stringstream s; s.width (width); @@ -771,13 +773,109 @@ std::string format (double value, int width, int precision) } //////////////////////////////////////////////////////////////////////////////// -std::string format (double value) +const std::string format (double value) { std::stringstream s; s << value; return s.str (); } +//////////////////////////////////////////////////////////////////////////////// +static void replace_positional ( + std::string& fmt, + const std::string& from, + const std::string& to) +{ + std::string::size_type pos = 0; + while ((pos = fmt.find (from, pos)) != std::string::npos) + { + fmt.replace (pos, from.length (), to); + pos += to.length (); + } +} + +//////////////////////////////////////////////////////////////////////////////// +const std::string format ( + const std::string& fmt, + const std::string& arg1) +{ + std::string output = fmt; + replace_positional (output, "{1}", arg1); + return output; +} + +//////////////////////////////////////////////////////////////////////////////// +const std::string format ( + const std::string& fmt, + int arg1) +{ + std::string output = fmt; + replace_positional (output, "{1}", format (arg1)); + return output; +} + +//////////////////////////////////////////////////////////////////////////////// +const std::string format ( + const std::string& fmt, + const std::string& arg1, + const std::string& arg2) +{ + std::string output = fmt; + replace_positional (output, "{1}", arg1); + replace_positional (output, "{2}", arg2); + return output; +} + +//////////////////////////////////////////////////////////////////////////////// +const std::string format ( + const std::string& fmt, + const std::string& arg1, + int arg2) +{ + std::string output = fmt; + replace_positional (output, "{1}", arg1); + replace_positional (output, "{2}", format (arg2)); + return output; +} + +//////////////////////////////////////////////////////////////////////////////// +const std::string format ( + const std::string& fmt, + int arg1, + const std::string& arg2) +{ + std::string output = fmt; + replace_positional (output, "{1}", format (arg1)); + replace_positional (output, "{2}", arg2); + return output; +} + +//////////////////////////////////////////////////////////////////////////////// +const std::string format ( + const std::string& fmt, + int arg1, + int arg2) +{ + std::string output = fmt; + replace_positional (output, "{1}", format (arg1)); + replace_positional (output, "{2}", format (arg2)); + return output; +} + +//////////////////////////////////////////////////////////////////////////////// +const std::string format ( + const std::string& fmt, + const std::string& arg1, + const std::string& arg2, + const std::string& arg3) +{ + std::string output = fmt; + replace_positional (output, "{1}", arg1); + replace_positional (output, "{2}", arg2); + replace_positional (output, "{3}", arg3); + return output; +} + //////////////////////////////////////////////////////////////////////////////// std::string leftJustify (const int input, const int width) { diff --git a/src/text.h b/src/text.h index b82695ec4..144226bc4 100644 --- a/src/text.h +++ b/src/text.h @@ -64,12 +64,20 @@ std::string::size_type find (const std::string&, const std::string&, bool sensit std::string::size_type find (const std::string&, const std::string&, std::string::size_type, bool sensitive = true); int strippedLength (const std::string&); std::string cutOff (const std::string&, std::string::size_type); -std::string format (char); -std::string format (int); -std::string formatHex (int); -std::string format (float, int, int); -std::string format (double, int, int); -std::string format (double); +const std::string format (char); +const std::string format (int); +const std::string formatHex (int); +const std::string format (float, int, int); +const std::string format (double, int, int); +const std::string format (double); +const std::string format (const std::string&, const std::string&); +const std::string format (const std::string&, int); +const std::string format (const std::string&, const std::string&, const std::string&); +const std::string format (const std::string&, const std::string&, int); +const std::string format (const std::string&, int, const std::string& arg2); +const std::string format (const std::string&, int, int); +const std::string format (const std::string&, const std::string&, const std::string&, const std::string&); + std::string leftJustify (const int, const int); std::string leftJustify (const std::string&, const int); std::string rightJustify (const int, const int); diff --git a/test/.gitignore b/test/.gitignore index cc60fbb39..33c6f6bba 100644 --- a/test/.gitignore +++ b/test/.gitignore @@ -12,6 +12,7 @@ dom.t duration.t file.t filt.t +i18n.t json.t lisp.t list.t diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index c69ef7ca2..6069bbf67 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -6,7 +6,7 @@ include_directories (${CMAKE_SOURCE_DIR}/src ${TASK_INCLUDE_DIRS}) set (test_SRCS att.t autocomplete.t color.t config.t date.t directory.t dom.t - duration.t file.t filt.t json.t list.t nibbler.t path.t + duration.t file.t filt.t i18n.t json.t list.t nibbler.t path.t record.t rx.t seq.t subst.t t.benchmark.t t.t taskmod.t tdb.t tdb2.t text.t uri.t util.t variant.t view.t json_test) diff --git a/test/i18n.t.cpp b/test/i18n.t.cpp new file mode 100644 index 000000000..2259fb50a --- /dev/null +++ b/test/i18n.t.cpp @@ -0,0 +1,75 @@ +//////////////////////////////////////////////////////////////////////////////// +// taskwarrior - a command line task list manager. +// +// Copyright 2006 - 2011, Paul Beckingham, Federico Hernandez. +// 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 +#include +#include + +#include +#include +#include + +Context context; + +//////////////////////////////////////////////////////////////////////////////// +int main (int argc, char** argv) +{ + UnitTest t (11); + + try + { + t.is (format ("pre {1} post", "mid"), "pre mid post", "format 1a"); + t.is (format ("pre {1}{1} post", "mid"), "pre midmid post", "format 1b"); + t.is (format ("pre {1} post", 0), "pre 0 post", "format 1c"); + t.is (format ("pre {1}{1} post", 0), "pre 00 post", "format 1d"); + + t.is (format ("pre {1}{2} post", "one", "two"), "pre onetwo post", "format 2a"); + t.is (format ("pre {2}{1} post", "one", "two"), "pre twoone post", "format 2b"); + t.is (format ("pre {1}{2} post", "one", 2), "pre one2 post", "format 2c"); + t.is (format ("pre {1}{2} post", 1, "two"), "pre 1two post", "format 2d"); + t.is (format ("pre {1}{2} post", 1, 2), "pre 12 post", "format 2e"); + + t.is (format ("pre {1}{2}{3} post", "one", "two", "three"), "pre onetwothree post", "format 3a"); + t.is (format ("pre {3}{1}{2} post", "one", "two", "three"), "pre threeonetwo post", "format 3b"); + } + + catch (std::string& error) + { + t.diag (error); + return -1; + } + + catch (...) + { + t.diag ("Unknown error."); + return -2; + } + + return 0; +} + +////////////////////////////////////////////////////////////////////////////////