Add api to get and set doubles and lists of doubles. (#164719, Maurizio
authorMatthias Clasen <mclasen@redhat.com>
Wed, 19 Apr 2006 02:59:37 +0000 (02:59 +0000)
committerMatthias Clasen <matthiasc@src.gnome.org>
Wed, 19 Apr 2006 02:59:37 +0000 (02:59 +0000)
2006-04-18  Matthias Clasen  <mclasen@redhat.com>

* glib/gkeyfile.h:
* glib/glib.symbols:
* glib/gkeyfile.c: Add api to get and set doubles and
lists of doubles.  (#164719, Maurizio Monge, Dom Lachowicz)

* tests/keyfile-test.c: Add tests for new api.

ChangeLog
ChangeLog.pre-2-12
docs/reference/ChangeLog
docs/reference/glib/glib-sections.txt
glib/gkeyfile.c
glib/gkeyfile.h
glib/glib.symbols
tests/keyfile-test.c

index f047781e708942a9e4df17160f769b560eda3b6f..4e34d76f3e7d79c4076714d8bc0f5d0171a66d06 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
 2006-04-18  Matthias Clasen  <mclasen@redhat.com>
 
+       * glib/gkeyfile.h:
+       * glib/glib.symbols:
+       * glib/gkeyfile.c: Add api to get and set doubles and 
+       lists of doubles.  (#164719, Maurizio Monge, Dom Lachowicz)
+
+       * tests/keyfile-test.c: Add tests for new api.
+
        * glib/gkeyfile.c (g_key_file_add_group): Accept duplicate
        groups.  (#157877, Sebastien Bacher)
 
index f047781e708942a9e4df17160f769b560eda3b6f..4e34d76f3e7d79c4076714d8bc0f5d0171a66d06 100644 (file)
@@ -1,5 +1,12 @@
 2006-04-18  Matthias Clasen  <mclasen@redhat.com>
 
+       * glib/gkeyfile.h:
+       * glib/glib.symbols:
+       * glib/gkeyfile.c: Add api to get and set doubles and 
+       lists of doubles.  (#164719, Maurizio Monge, Dom Lachowicz)
+
+       * tests/keyfile-test.c: Add tests for new api.
+
        * glib/gkeyfile.c (g_key_file_add_group): Accept duplicate
        groups.  (#157877, Sebastien Bacher)
 
index e825507b7b86014d0f67af50851df569e6017d68..66250486cdce4428feb4b540a8e97dbffdb2f793 100644 (file)
@@ -1,3 +1,7 @@
+2006-04-18  Matthias Clasen  <mclasen@redhat.com>
+
+       * glib/glib-sections.txt: Add new keyfile api
+
 2006-04-18  Matthias Clasen  <mclasen@redhat.com>
 
        * gobject/tut_gobject.xml: Say that ref/unref are thread-safe now.  
index 786b832aa52d834521089d8e2f0a90c33a1158da..cd832eca6b0f5e7599cc76f343c8ef7f43fa8610 100644 (file)
@@ -1464,10 +1464,12 @@ g_key_file_get_string
 g_key_file_get_locale_string
 g_key_file_get_boolean
 g_key_file_get_integer
+g_key_file_get_double
 g_key_file_get_string_list
 g_key_file_get_locale_string_list
 g_key_file_get_boolean_list
 g_key_file_get_integer_list
+g_key_file_get_double_list
 g_key_file_get_comment
 
 <SUBSECTION>
@@ -1476,10 +1478,12 @@ g_key_file_set_string
 g_key_file_set_locale_string
 g_key_file_set_boolean
 g_key_file_set_integer
+g_key_file_set_double
 g_key_file_set_string_list
 g_key_file_set_locale_string_list
 g_key_file_set_boolean_list
 g_key_file_set_integer_list
+g_key_file_set_double_list
 g_key_file_set_comment
 g_key_file_remove_group
 g_key_file_remove_key
index eeb8ee12dcad30895c5d4291295a47c7c8fd1c4d..4456644cbc9c05d6b3b943305425334d1873ec79 100644 (file)
@@ -152,6 +152,9 @@ static gint                  g_key_file_parse_value_as_integer (GKeyFile
                                                                GError                **error);
 static gchar                *g_key_file_parse_integer_as_value (GKeyFile               *key_file,
                                                                gint                    value);
+static gdouble               g_key_file_parse_value_as_double  (GKeyFile               *key_file,
+                                                                const gchar            *value,
+                                                                GError                **error);
 static gboolean              g_key_file_parse_value_as_boolean (GKeyFile               *key_file,
                                                                const gchar            *value,
                                                                GError                **error);
@@ -2153,6 +2156,218 @@ g_key_file_set_integer_list (GKeyFile     *key_file,
   g_string_free (values, TRUE);
 }
 
+/**
+ * g_key_file_get_double:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ * @key: a key
+ * @error: return location for a #GError
+ *
+ * Returns the value associated with @key under @group_name as an
+ * integer. If @group_name is %NULL, the start_group is used.
+ *
+ * If @key cannot be found then the return value is undefined and
+ * @error is set to #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if
+ * the value associated with @key cannot be interpreted as a double
+ * then the return value is also undefined and @error is set to
+ * #G_KEY_FILE_ERROR_INVALID_VALUE.
+ *
+ * Return value: the value associated with the key as a double.
+ *
+ * Since: 2.12
+ **/
+gdouble
+g_key_file_get_double  (GKeyFile     *key_file,
+                        const gchar  *group_name,
+                        const gchar  *key,
+                        GError      **error)
+{
+  GError *key_file_error;
+  gchar *value;
+  gdouble double_value;
+
+  g_return_val_if_fail (key_file != NULL, -1);
+  g_return_val_if_fail (group_name != NULL, -1);
+  g_return_val_if_fail (key != NULL, -1);
+
+  key_file_error = NULL;
+
+  value = g_key_file_get_value (key_file, group_name, key, &key_file_error);
+
+  if (key_file_error)
+    {
+      g_propagate_error (error, key_file_error);
+      return 0;
+    }
+
+  double_value = g_key_file_parse_value_as_double (key_file, value,
+                                                  &key_file_error);
+  g_free (value);
+
+  if (key_file_error)
+    {
+      if (g_error_matches (key_file_error,
+                           G_KEY_FILE_ERROR,
+                           G_KEY_FILE_ERROR_INVALID_VALUE))
+        {
+          g_set_error (error, G_KEY_FILE_ERROR,
+                       G_KEY_FILE_ERROR_INVALID_VALUE,
+                       _("Key file contains key '%s' in group '%s' "
+                         "which has value that cannot be interpreted."), key,
+                       group_name);
+          g_error_free (key_file_error);
+        }
+      else
+        g_propagate_error (error, key_file_error);
+    }
+
+  return double_value;
+}
+
+/**
+ * g_key_file_set_double:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ * @key: a key
+ * @value: an double value
+ *
+ * Associates a new double value with @key under @group_name.
+ * If @key cannot be found then it is created. If @group_name
+ * is %NULL, the start group is used.
+ *
+ * Since: 2.12
+ **/
+void
+g_key_file_set_double  (GKeyFile    *key_file,
+                        const gchar *group_name,
+                        const gchar *key,
+                        gdouble      value)
+{
+  gchar result[G_ASCII_DTOSTR_BUF_SIZE];
+
+  g_return_if_fail (key_file != NULL);
+  g_return_if_fail (group_name != NULL);
+  g_return_if_fail (key != NULL);
+
+  g_ascii_dtostr ( result, sizeof (result), value );
+  g_key_file_set_value (key_file, group_name, key, result);
+}
+
+/**
+ * g_key_file_get_double_list:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ * @key: a key
+ * @length: the number of doubles returned
+ * @error: return location for a #GError
+ *
+ * Returns the values associated with @key under @group_name as
+ * doubles. If @group_name is %NULL, the start group is used.
+ *
+ * If @key cannot be found then the return value is undefined and
+ * @error is set to #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if
+ * the values associated with @key cannot be interpreted as doubles
+ * then the return value is also undefined and @error is set to
+ * #G_KEY_FILE_ERROR_INVALID_VALUE.
+ *
+ * Return value: the values associated with the key as a double
+ *
+ * Since: 2.12
+ **/
+gdouble *
+g_key_file_get_double_list  (GKeyFile     *key_file,
+                             const gchar  *group_name,
+                             const gchar  *key,
+                             gsize        *length,
+                             GError      **error)
+{
+  GError *key_file_error = NULL;
+  gchar **values;
+  gdouble *double_values;
+  gsize i, num_doubles;
+
+  g_return_val_if_fail (key_file != NULL, NULL);
+  g_return_val_if_fail (group_name != NULL, NULL);
+  g_return_val_if_fail (key != NULL, NULL);
+
+  values = g_key_file_get_string_list (key_file, group_name, key,
+                                       &num_doubles, &key_file_error);
+
+  if (key_file_error)
+    g_propagate_error (error, key_file_error);
+
+  if (!values)
+    return NULL;
+
+  double_values = g_new0 (gdouble, num_doubles);
+
+  for (i = 0; i < num_doubles; i++)
+    {
+      double_values[i] = g_key_file_parse_value_as_double (key_file,
+                                                          values[i],
+                                                          &key_file_error);
+
+      if (key_file_error)
+        {
+          g_propagate_error (error, key_file_error);
+          g_strfreev (values);
+          g_free (double_values);
+
+          return NULL;
+        }
+    }
+  g_strfreev (values);
+
+  if (length)
+    *length = num_doubles;
+
+  return double_values;
+}
+
+/**
+ * g_key_file_set_double_list:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ * @key: a key
+ * @list: an array of double values
+ * @length: number of double values in @list
+ *
+ * Associates a list of double values with @key under
+ * @group_name.  If @key cannot be found then it is created.
+ * If @group_name is %NULL the start group is used.
+ *
+ * Since: 2.21
+ **/
+void
+g_key_file_set_double_list (GKeyFile     *key_file,
+                           const gchar  *group_name,
+                           const gchar  *key,
+                           gdouble       list[],
+                           gsize         length)
+{
+  GString *values;
+  gsize i;
+
+  g_return_if_fail (key_file != NULL);
+  g_return_if_fail (group_name != NULL);
+  g_return_if_fail (key != NULL);
+  g_return_if_fail (list != NULL);
+
+  values = g_string_sized_new (length * 16);
+  for (i = 0; i < length; i++)
+    {
+      gchar result[G_ASCII_DTOSTR_BUF_SIZE];
+
+      g_ascii_dtostr( result, sizeof (result), list[i] );
+
+      g_string_append (values, result);
+      g_string_append_c (values, ';');
+    }
+
+  g_key_file_set_value (key_file, group_name, key, values->str);
+  g_string_free (values, TRUE);
+}
+
 static void
 g_key_file_set_key_comment (GKeyFile             *key_file,
                             const gchar          *group_name,
@@ -3249,6 +3464,24 @@ g_key_file_parse_integer_as_value (GKeyFile *key_file,
   return g_strdup_printf ("%d", value);
 }
 
+static gdouble
+g_key_file_parse_value_as_double  (GKeyFile     *key_file,
+                                   const gchar  *value,
+                                   GError      **error)
+{
+  gchar *end_of_valid_d;
+  gdouble double_value = 0;
+
+  double_value = g_ascii_strtod (value, &end_of_valid_d);
+
+  if (*end_of_valid_d != '\0')
+    g_set_error (error, G_KEY_FILE_ERROR,
+                 G_KEY_FILE_ERROR_INVALID_VALUE,
+                 _("Value '%s' cannot be interpreted as a float number."), value);
+
+  return double_value;
+}
+
 static gboolean
 g_key_file_parse_value_as_boolean (GKeyFile     *key_file,
                                   const gchar  *value,
index 08c0fe554607d7d76ac1c5228e4dafc5a54f705d..8014550983e700c2267646f2b9057607c10a0114 100644 (file)
@@ -126,6 +126,14 @@ void      g_key_file_set_integer            (GKeyFile             *key_file,
                                             const gchar          *group_name,
                                             const gchar          *key,
                                             gint                  value);
+gdouble   g_key_file_get_double             (GKeyFile             *key_file,
+                                             const gchar          *group_name,
+                                             const gchar          *key,
+                                             GError              **error);
+void      g_key_file_set_double             (GKeyFile             *key_file,
+                                             const gchar          *group_name,
+                                             const gchar          *key,
+                                             gdouble               value);
 gchar   **g_key_file_get_string_list        (GKeyFile             *key_file,
                                             const gchar          *group_name,
                                             const gchar          *key,
@@ -163,6 +171,16 @@ gint     *g_key_file_get_integer_list       (GKeyFile             *key_file,
                                             const gchar          *key,
                                             gsize                *length,
                                             GError              **error) G_GNUC_MALLOC;
+void      g_key_file_set_double_list        (GKeyFile             *key_file,
+                                             const gchar          *group_name,
+                                             const gchar          *key,
+                                             gdouble               list[],
+                                             gsize                 length);
+gdouble  *g_key_file_get_double_list        (GKeyFile             *key_file,
+                                             const gchar          *group_name,
+                                             const gchar          *key,
+                                             gsize                *length,
+                                             GError              **error) G_GNUC_MALLOC;
 void      g_key_file_set_integer_list       (GKeyFile             *key_file,
                                             const gchar          *group_name,
                                             const gchar          *key,
index 6c98a3b48cc1e2563335019b15fbf0fdbec68641..2a9a27d20da9fbf940676ab4cab30f9e981e8040 100644 (file)
@@ -475,6 +475,8 @@ g_key_file_get_boolean
 g_key_file_get_boolean_list G_GNUC_MALLOC
 g_key_file_get_comment G_GNUC_MALLOC
 g_key_file_get_groups G_GNUC_MALLOC
+g_key_file_get_double
+g_key_file_get_double_list G_GNUC_MALLOC
 g_key_file_get_integer
 g_key_file_get_integer_list G_GNUC_MALLOC
 g_key_file_get_keys G_GNUC_MALLOC
@@ -496,6 +498,8 @@ g_key_file_remove_key
 g_key_file_set_boolean
 g_key_file_set_boolean_list
 g_key_file_set_comment
+g_key_file_set_double
+g_key_file_set_double_list
 g_key_file_set_integer
 g_key_file_set_integer_list
 g_key_file_set_list_separator
index 7680881ccc6892efe26a7477aa1fcbcbbe23e5b8..e9ec9229f63b9c59f29e7767923d9ec61fa2877c 100644 (file)
@@ -198,6 +198,49 @@ check_integer_list_value (GKeyFile    *keyfile,
   g_free (value);
 }
 
+static void
+check_double_list_value (GKeyFile    *keyfile,
+                         const gchar *group,
+                         const gchar *key,
+                         ...)
+{
+  gint i;
+  gdouble v, *value;
+  va_list args;
+  gsize len;
+  GError *error = NULL;
+
+  value = g_key_file_get_double_list (keyfile, group, key, &len, &error);
+  check_no_error (&error);
+  g_assert (value != NULL);
+  
+  va_start (args, key);
+  i = 0;
+  v = va_arg (args, gdouble);
+  while (v != -100)
+    {
+      if (i == len)
+       {
+         g_print ("Group %s key %s: list too short (%d)\n", 
+                  group, key, i);      
+         exit (1);
+       }
+      if (value[i] != v)
+       {
+         g_print ("Group %s key %s: mismatch at %d, expected %e, got %e\n", 
+                  group, key, i, v, value[i]);      
+         exit (1);
+       }
+
+      i++;
+      v = va_arg (args, gdouble);
+    }
+
+  va_end (args);
+  
+  g_free (value);
+}
+
 static void
 check_boolean_list_value (GKeyFile    *keyfile,
                          const gchar *group,
@@ -285,6 +328,27 @@ check_integer_value (GKeyFile    *keyfile,
     }
 }
 
+static void
+check_double_value (GKeyFile    *keyfile,
+                    const gchar *group,
+                    const gchar *key,
+                    gdouble      expected) 
+{
+  GError *error = NULL;
+  gdouble value;
+
+  value = g_key_file_get_double (keyfile, group, key, &error);
+  check_no_error (&error);
+
+  if (value != expected)
+    {
+      g_print ("Group %s key %s: "
+              "expected integer value %e, actual value %e\n",
+              group, key, expected, value);      
+      exit (1);
+    }
+}
+
 static void
 check_name (const gchar *what,
            const gchar *value,
@@ -605,9 +669,9 @@ test_boolean (void)
   g_key_file_free (keyfile);
 }
 
-/* check parsing of integer values */
+/* check parsing of integer and double values */
 static void
-test_integer (void)
+test_number (void)
 {
   GKeyFile *keyfile;
   GError *error = NULL;
@@ -620,6 +684,9 @@ test_integer (void)
     "key4=2324431\n"
     "key5=-2324431\n"
     "key6=000111\n"
+    "dkey1=000111\n"
+    "dkey2=145.45\n"
+    "dkey3=-3453.7\n"
     "[invalid]\n"
     "key1=0xffff\n"
     "key2=0.5\n"
@@ -634,6 +701,9 @@ test_integer (void)
   check_integer_value (keyfile, "valid", "key4", 2324431);
   check_integer_value (keyfile, "valid", "key5", -2324431);
   check_integer_value (keyfile, "valid", "key6", 111);
+  check_double_value (keyfile, "valid", "dkey1", 111.0);
+  check_double_value (keyfile, "valid", "dkey2", 145.45);
+  check_double_value (keyfile, "valid", "dkey3", -3453.7);
 
   g_key_file_get_integer (keyfile, "invalid", "key1", &error);
   check_error (&error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE);
@@ -727,7 +797,8 @@ test_lists (void)
     "key5=true;false\n"
     "key6=1;0;-1\n"
     "key7= 1 ; 0 ; -1 \n"
-    "key8=v1\\,v2\n";
+    "key8=v1\\,v2\n"
+    "key9=0;1.3456;-76532.456\n";
   
   keyfile = load_data (data, 0);
 
@@ -737,6 +808,7 @@ test_lists (void)
   check_string_list_value (keyfile, "valid", "key4", "v1;v2", NULL);
   check_boolean_list_value (keyfile, "valid", "key5", TRUE, FALSE, -100);
   check_integer_list_value (keyfile, "valid", "key6", 1, 0, -1, -100);
+  check_double_list_value (keyfile, "valid", "key9", 0.0, 1.3456, -76532.456, -100.0);
   /* maybe these should be valid */
   /* check_integer_list_value (keyfile, "valid", "key7", 1, 0, -1, -100);*/
   /* check_string_list_value (keyfile, "valid", "key8", "v1\\,v2", NULL);*/
@@ -921,7 +993,7 @@ main (int argc, char *argv[])
   test_listing ();
   test_string ();
   test_boolean ();
-  test_integer ();
+  test_number ();
   test_locale_string ();
   test_lists ();
   test_group_remove ();