After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 506394 - Compose without format string
Compose without format string
Status: RESOLVED FIXED
Product: glibmm
Classification: Bindings
Component: strings
2.15.x
Other All
: Normal enhancement
: ---
Assigned To: gtkmm-forge
gtkmm-forge
Depends on:
Blocks:
 
 
Reported: 2007-12-30 10:31 UTC by Szilárd Pfeiffer
Modified: 2009-01-08 17:46 UTC
See Also:
GNOME target: ---
GNOME version: Unversioned Enhancement



Description Szilárd Pfeiffer 2007-12-30 10:31:34 UTC
It is not possible to compose without format string. Error occurs if only a literal string or numeric constant or variable is given.

In my humble opinion it would be easier to use the compose API if it was possible. I'd suggest something like the following:


Index: glib/glibmm/ustring.h
===================================================================
--- glib/glibmm/ustring.h       (revision 490)
+++ glib/glibmm/ustring.h       (working copy)
@@ -609,6 +609,15 @@
 //! @name Message formatting.
 //! @{
 
+  /*
+   * @param a1 The argument to substitute for "%1".
+   * @return The substituted message string.
+   * @throw Glib::ConvertError
+   */ 
+  template <class T1>
+  static inline
+  ustring compose(const T1& a1);
+
   /*! Substitute placeholders in a format string with the referenced arguments.
    * The template string should be in <tt>qt-format</tt>, that is
    * <tt>"%1"</tt>, <tt>"%2"</tt>, ..., <tt>"%9"</tt> are used as placeholders
@@ -1240,7 +1249,6 @@
 
 public:
   explicit inline Stringify(const T& arg) : string_ (ustring::format(arg)) {}
-  explicit inline Stringify(const char* arg) : string_ (arg) {}
   inline const ustring* ptr() const { return &string_; }
 };
 
@@ -1261,6 +1269,16 @@
 
 template <class T1>
 inline // static
+ustring ustring::compose(const T1& a1)
+{
+  const ustring::Stringify<T1> s0 (a1);
+
+  const ustring *const argv[] = { s0.ptr() };
+  return ustring::compose_argv("%1", G_N_ELEMENTS(argv), argv);
+}
+
+template <class T1>
+inline // static
 ustring ustring::compose(const ustring& fmt, const T1& a1)
 {
   const ustring::Stringify<T1> s1 (a1);
Index: examples/compose/main.cc
===================================================================
--- examples/compose/main.cc    (revision 490)
+++ examples/compose/main.cc    (working copy)
@@ -32,7 +32,7 @@
   const int    i = int(a / (a + b) * 40.0);
 
   std::cout
-    << ustring::compose("%1 is lower than %2.", a, b)
+    << ustring::compose(a) << ustring::compose(" is lower than ") << ustring::compose(b) << ustring::compose('.')
     << std::endl
     << ustring::compose("%2 is greater than %1.", a, b)
     << std::endl
Comment 1 Daniel Elstner 2007-12-31 03:05:30 UTC
Can't you just use ustring::format() if you don't want to compose?
Comment 2 Szilárd Pfeiffer 2007-12-31 10:27:15 UTC
You're right. The problem is not so serious in a simple case, when you want to write out the value of a variable.

Actually, I've tried to write a debug macro with variable number of arguments, so I haven't got information about the existence of the format string.

Example:

#include <glibmm.h>

#include <iostream>

#define debug(format, ...) std::cout << Glib::ustring::compose(format, ## __VA_ARGS__)

int main(int, char**)
{
  const char *constant_string = "constant string";

  Glib::init();

  debug("literal string\n");
  debug("%1\n", constant_string);
  debug("%1 %2\n", "formatted", "string");

  return 0;
}

The patch in comment 0 compose API would be more printf-style, but I don't know whether it is a goal.
Comment 3 Murray Cumming 2008-01-20 17:50:16 UTC
So, Daniel, is this patch something that we want?
Comment 4 Daniel Elstner 2008-12-04 14:20:08 UTC
Sorry for the heavy delay.

No, I don't think this patch is appropriate.  I agree with the intent to make the API more orthogonal.  However, the interpretation of the single-argument compose(arg) as compose("%1", arg) is wrong.  Rather than no format string, this overload would take _only_ a format string and nothing else.  That's also the way printf() works -- there is no printf() without a format string.

So it would look like this:

    ustring::compose(const ustring& fmt)
    {
      return ustring::compose_argv(fmt, 0, 0);
    }

Which is, apart from checking the format string for incorrect argument references, essentially the same as simply

    ustring::compose(const ustring& fmt)
    {
      return fmt;
    }

We might want to add this for reasons of orthogonality, but it isn't terribly important.  It wouldn't break API or ABI though, as it's just a trivial addition.
Comment 5 Murray Cumming 2009-01-03 13:59:06 UTC
Szilárd, so do you agree that we can close this bug?
Comment 6 Szilárd Pfeiffer 2009-01-07 12:17:39 UTC
(In reply to comment #5)
> Szilárd, so do you agree that we can close this bug?
> 

I have no objection.
Comment 7 Daniel Elstner 2009-01-08 17:46:39 UTC
2009-01-08  Daniel Elstner  <danielk@openismus.com>

	* glib/glibmm/ustring.h (ustring::compose): Add an overload which
	takes only a format string and no arguments to be substituted.  It
	is essentially a null-operation as long as the format string does
	not contain any invalid argument references.  Bug #506394.

Closing.