summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorDaniel Boles <dboles@src.gnome.org>2019-06-20 17:58:04 +0100
committerDaniel Boles <dboles@src.gnome.org>2019-06-20 17:58:04 +0100
commit79f7e208c49ace269c4f1aa62cbb37d33e0e2fab (patch)
treebb9df5804d6d57fecdcd1773324e0d3cf11f7456 /tests
parent199a6aab97f3a44fc627cddd6cfeb1f477d1ff85 (diff)
downloadglibmm-79f7e208c49ace269c4f1aa62cbb37d33e0e2fab.tar.gz
ustring: Add sprintf(), wrapping g_strdup_printf()
Add another way to produce formatted ustrings, this time using printf syntax, by forwarding arguments to g_strdup_printf() and then copying the result into the returned ustring. This includes a private ustring::sprintify() function that by default just forward its argument but can be overloaded to do something else. In this commit, that is overloaded for ustring and std::string so that their .c_str() is passed to printf instead, avoiding the ugliness of users always having to write .c_str() in their own lists of arguments. Note that the same lack of type safety as plagues printf() and all its variants (in both C and GLib) applies here: the arguments are just forwarded on, so if you include too few or the wrong types for the placeholders you specify, you invoke undefined behaviour just as in C. For reasons like that, C++'s preference of streams over stdio, and the hope that we'll eventually get an actual nice string-formatting solution in the C++ Standard, I don't go out of my way to shout about this in the documentation. Users who really want sprintf() will find it, without us having to shout too loudly about it and risk being seen as recommending it more than anything else. It's here for those who know they need it. https://gitlab.gnome.org/GNOME/glibmm/issues/21
Diffstat (limited to 'tests')
-rw-r--r--tests/Makefile.am2
-rw-r--r--tests/glibmm_ustring_sprintf/main.cc55
2 files changed, 57 insertions, 0 deletions
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 339eeada..3f6f81c9 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -40,6 +40,7 @@ check_PROGRAMS = \
glibmm_objectbase_move/test \
glibmm_ustring_compose/test \
glibmm_ustring_format/test \
+ glibmm_ustring_sprintf/test \
glibmm_value/test \
glibmm_variant/test \
glibmm_vector/test \
@@ -113,6 +114,7 @@ glibmm_objectbase_move_test_SOURCES = glibmm_objectbase_move/main.cc \
glibmm_object/test_derived_object.h
glibmm_ustring_compose_test_SOURCES = glibmm_ustring_compose/main.cc
glibmm_ustring_format_test_SOURCES = glibmm_ustring_format/main.cc
+glibmm_ustring_sprintf_test_SOURCES = glibmm_ustring_sprintf/main.cc
glibmm_value_test_SOURCES = glibmm_value/main.cc
glibmm_variant_test_SOURCES = glibmm_variant/main.cc
glibmm_vector_test_SOURCES = glibmm_vector/main.cc
diff --git a/tests/glibmm_ustring_sprintf/main.cc b/tests/glibmm_ustring_sprintf/main.cc
new file mode 100644
index 00000000..232be152
--- /dev/null
+++ b/tests/glibmm_ustring_sprintf/main.cc
@@ -0,0 +1,55 @@
+#include <glibmm/init.h>
+#include <glibmm/ustring.h>
+
+#include <cstdlib>
+#include <iostream>
+
+namespace {
+
+template <class... Ts>
+void
+test(const Glib::ustring& expected, const Glib::ustring& fmt, const Ts&... ts)
+{
+ const auto actual = Glib::ustring::sprintf(fmt, ts...);
+
+ if (actual != expected)
+ {
+ std::cerr << "error testing Glib::ustring::sprintf():\n"
+ "expected (" << expected.size() << "):\n" << expected << "\n\n"
+ "actual (" << actual .size() << "):\n" << actual << "\n";
+
+ std::exit(EXIT_FAILURE);
+ }
+}
+
+} // anonymous namespace
+
+int
+main(int, char**)
+{
+ // Don't use the user's preferred locale. The decimal delimiter may be ','
+ // instead of the expected '.'.
+ Glib::set_init_to_users_preferred_locale(false);
+
+ Glib::init();
+
+ test("No formatting here, just a boring string",
+ "No formatting here, just a boring string");
+
+ test("Interpolating another string: \"here it is\" and there it was gone.",
+ "Interpolating another string: \"%s\" and there it was gone.", "here it is");
+
+ test("some stuff and then an int: 42",
+ "some stuff and then an int: %d", 42);
+
+ const auto greeting = std::string{"Hi"};
+ const auto name = Glib::ustring{"Dennis"};
+ const auto your_cows = 3;
+ const auto my_cows = 11;
+ const auto cow_percentage = 100.0 * your_cows / my_cows;
+ test("Hi, Dennis! You have 3 cows.\nThat's about 27.27% of the 11 cows I have.",
+ "%s, %s! You have %d cows.\nThat's about %0.2f%% of the %d cows I have.",
+ greeting, name, your_cows, cow_percentage, my_cows);
+
+ return EXIT_SUCCESS;
+}