[units] Do not be locale-dependant on string conversion
authorEmmanuele Bassi <ebassi@linux.intel.com>
Fri, 14 Aug 2009 14:59:29 +0000 (15:59 +0100)
committerEmmanuele Bassi <ebassi@linux.intel.com>
Fri, 14 Aug 2009 15:05:33 +0000 (16:05 +0100)
When dumping a ClutterUnits structure to a string we are using a bare
g_strdup_printf(), which unfortunately is locale dependant. So, for
instance, a type of CLUTTER_UNIT_EM and a value of 42 are stringified
as:

        C:      42.00 em
        en_GB   42.00 em
        it_IT   42,00 em
        fr_FR   42,00 em

This would not be a problem -- clutter_units_from_string() allows both
'.' and ',' as fractionary part delimiters. The test suite, on the
other hand, does not know that, and it checks for exact matches with
the C locale.

Calling setlocale(LC_ALL,"C") at the beginning of the conformance test
suite is not a good idea, because it would prevent external testing; and
it's a lame cop out from doing exactly what we have to do -- pick a format
and stick with it.

Like other platforms, languages and frameworks before us, we opt to
be less liberal in what we create; so, we choose to always stringify
ClutterUnits with fractionary parts using '.' as the delimiter.

Fixes bug:

  http://bugzilla.openedhand.com/show_bug.cgi?id=1763

clutter/clutter-units.c

index 75802b8..e5fe5a3 100644 (file)
@@ -499,30 +499,32 @@ gchar *
 clutter_units_to_string (const ClutterUnits *units)
 {
   const gchar *unit_name = NULL;
-  gchar *fmt = NULL;
+  const gchar *fmt = NULL;
+  gchar buf[G_ASCII_DTOSTR_BUF_SIZE];
 
   g_return_val_if_fail (units != NULL, NULL);
 
   switch (units->unit_type)
     {
+    /* special case: there is no such thing as "half a pixel", so
+     * we round up to the nearest integer using C default
+     */
+    case CLUTTER_UNIT_PIXEL:
+      return g_strdup_printf ("%d px", (int) units->value);
+
     case CLUTTER_UNIT_MM:
       unit_name = "mm";
-      fmt = g_strdup_printf ("%.2f", units->value);
+      fmt = "%.2f";
       break;
 
     case CLUTTER_UNIT_POINT:
       unit_name = "pt";
-      fmt = g_strdup_printf ("%.1f", units->value);
+      fmt = "%.1f";
       break;
 
     case CLUTTER_UNIT_EM:
       unit_name = "em";
-      fmt = g_strdup_printf ("%.2f", units->value);
-      break;
-
-    case CLUTTER_UNIT_PIXEL:
-      unit_name = "px";
-      fmt = g_strdup_printf ("%d", (int) units->value);
+      fmt = "%.2f";
       break;
 
     default:
@@ -530,7 +532,9 @@ clutter_units_to_string (const ClutterUnits *units)
       break;
     }
 
-  return g_strconcat (fmt, " ", unit_name, NULL);
+  g_ascii_formatd (buf, G_ASCII_DTOSTR_BUF_SIZE, fmt, units->value);
+
+  return g_strconcat (buf, " ", unit_name, NULL);
 }
 
 /*