[glib] gvalue: Add explicitly signed g_value_get_schar() and g_value_set_schar()



commit f42fe6cdc056b77f74ff6e332389d444c50ae7dc
Author: Colin Walters <walters verbum org>
Date:   Thu Sep 22 16:08:35 2011 -0400

    gvalue: Add explicitly signed g_value_get_schar() and g_value_set_schar()
    
    The documentation for G_TYPE_CHAR says:
    
    "The type designated by G_TYPE_CHAR is unconditionally an 8-bit signed
     integer."
    
    However the return value for g_value_get_char() was just "char" which
    in C has an unspecified signedness; on e.g. x86 it's signed (which
    matches the GType), but on e.g. PowerPC or ARM, it's not.
    
    We can't break the old API, so we need to suck it up and add new API.
    Port most internal users, but keep some tests of the old API too.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=659870

 gio/gsettings-mapping.c        |    4 +-
 gio/tests/gsettings.c          |    6 ++--
 gobject/gclosure.c             |    2 +-
 gobject/glib-genmarshal.c      |    2 +-
 gobject/gmarshal.c             |    2 +-
 gobject/gobject.symbols        |    2 +
 gobject/gvaluetypes.c          |   42 +++++++++++++++++++++++++++++++++++++++-
 gobject/gvaluetypes.h          |    5 ++++
 gobject/tests/param.c          |   13 +++++++++--
 tests/gobject/gvalue-test.c    |    1 +
 tests/gobject/paramspec-test.c |   16 +++++++++++++++
 11 files changed, 83 insertions(+), 12 deletions(-)
---
diff --git a/gio/gsettings-mapping.c b/gio/gsettings-mapping.c
index fda7463..6a9c41b 100644
--- a/gio/gsettings-mapping.c
+++ b/gio/gsettings-mapping.c
@@ -346,7 +346,7 @@ g_settings_set_mapping (const GValue       *value,
       if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_BYTE))
         {
           if (G_VALUE_HOLDS_CHAR (value))
-            return g_variant_new_byte (g_value_get_char (value));
+            return g_variant_new_byte (g_value_get_schar (value));
           else
             return g_variant_new_byte (g_value_get_uchar (value));
         }
@@ -453,7 +453,7 @@ g_settings_get_mapping (GValue   *value,
       if (G_VALUE_HOLDS_UCHAR (value))
         g_value_set_uchar (value, g_variant_get_byte (variant));
       else if (G_VALUE_HOLDS_CHAR (value))
-        g_value_set_char (value, (gchar) g_variant_get_byte (variant));
+        g_value_set_schar (value, (gint8)g_variant_get_byte (variant));
       else
         return FALSE;
       return TRUE;
diff --git a/gio/tests/gsettings.c b/gio/tests/gsettings.c
index fce4978..2655ed7 100644
--- a/gio/tests/gsettings.c
+++ b/gio/tests/gsettings.c
@@ -718,7 +718,7 @@ typedef struct
 
   gboolean bool_prop;
   gboolean anti_bool_prop;
-  gchar byte_prop;
+  gint8 byte_prop;
   gint int16_prop;
   guint16 uint16_prop;
   gint int_prop;
@@ -771,7 +771,7 @@ test_object_get_property (GObject    *object,
       g_value_set_boolean (value, test_object->anti_bool_prop);
       break;
     case PROP_BYTE:
-      g_value_set_char (value, test_object->byte_prop);
+      g_value_set_schar (value, test_object->byte_prop);
       break;
     case PROP_UINT16:
       g_value_set_uint (value, test_object->uint16_prop);
@@ -829,7 +829,7 @@ test_object_set_property (GObject      *object,
       test_object->anti_bool_prop = g_value_get_boolean (value);
       break;
     case PROP_BYTE:
-      test_object->byte_prop = g_value_get_char (value);
+      test_object->byte_prop = g_value_get_schar (value);
       break;
     case PROP_INT16:
       test_object->int16_prop = g_value_get_int (value);
diff --git a/gobject/gclosure.c b/gobject/gclosure.c
index 5fd928b..36ec4b0 100644
--- a/gobject/gclosure.c
+++ b/gobject/gclosure.c
@@ -1029,7 +1029,7 @@ value_from_ffi_type (GValue *gvalue, gpointer *value)
       g_value_set_string (gvalue, *(gchar**)value);
       break;
     case G_TYPE_CHAR:
-      g_value_set_char (gvalue, *(gchar*)value);
+      g_value_set_schar (gvalue, *(gint8*)value);
       break;
     case G_TYPE_UCHAR:
       g_value_set_uchar (gvalue, *(guchar*)value);
diff --git a/gobject/glib-genmarshal.c b/gobject/glib-genmarshal.c
index 8afacdb..d79ae79 100644
--- a/gobject/glib-genmarshal.c
+++ b/gobject/glib-genmarshal.c
@@ -134,7 +134,7 @@ put_marshal_value_getters (void)
   fputs ("\n", fout);
   fputs ("#ifdef G_ENABLE_DEBUG\n", fout);
   fputs ("#define g_marshal_value_peek_boolean(v)  g_value_get_boolean (v)\n", fout);
-  fputs ("#define g_marshal_value_peek_char(v)     g_value_get_char (v)\n", fout);
+  fputs ("#define g_marshal_value_peek_char(v)     g_value_get_schar (v)\n", fout);
   fputs ("#define g_marshal_value_peek_uchar(v)    g_value_get_uchar (v)\n", fout);
   fputs ("#define g_marshal_value_peek_int(v)      g_value_get_int (v)\n", fout);
   fputs ("#define g_marshal_value_peek_uint(v)     g_value_get_uint (v)\n", fout);
diff --git a/gobject/gmarshal.c b/gobject/gmarshal.c
index bc53b5d..c7bcce4 100644
--- a/gobject/gmarshal.c
+++ b/gobject/gmarshal.c
@@ -8,7 +8,7 @@
 
 #ifdef G_ENABLE_DEBUG
 #define g_marshal_value_peek_boolean(v)  g_value_get_boolean (v)
-#define g_marshal_value_peek_char(v)     g_value_get_char (v)
+#define g_marshal_value_peek_char(v)     g_value_get_schar (v)
 #define g_marshal_value_peek_uchar(v)    g_value_get_uchar (v)
 #define g_marshal_value_peek_int(v)      g_value_get_int (v)
 #define g_marshal_value_peek_uint(v)     g_value_get_uint (v)
diff --git a/gobject/gobject.symbols b/gobject/gobject.symbols
index f03f551..d5b2522 100644
--- a/gobject/gobject.symbols
+++ b/gobject/gobject.symbols
@@ -218,6 +218,7 @@ g_value_set_int64
 g_value_set_long
 g_value_set_pointer
 g_value_set_static_string
+g_value_set_schar
 g_value_set_string
 g_value_set_string_take_ownership
 g_value_set_uchar
@@ -233,6 +234,7 @@ g_value_get_int
 g_value_get_int64
 g_value_get_long
 g_value_get_pointer
+g_value_get_schar
 g_value_get_string
 g_value_get_uchar
 g_value_get_uint
diff --git a/gobject/gvaluetypes.c b/gobject/gvaluetypes.c
index a05ccd9..c2850d1 100644
--- a/gobject/gvaluetypes.c
+++ b/gobject/gvaluetypes.c
@@ -636,6 +636,7 @@ _g_value_types_init (void)
  * @v_char: character value to be set
  *
  * Set the contents of a %G_TYPE_CHAR #GValue to @v_char.
+ * Deprecated: 2.32: This function's input type is broken, see g_value_set_schar()
  */
 void
 g_value_set_char (GValue *value,
@@ -650,9 +651,13 @@ g_value_set_char (GValue *value,
  * g_value_get_char:
  * @value: a valid #GValue of type %G_TYPE_CHAR
  *
- * Get the contents of a %G_TYPE_CHAR #GValue.
+ * Do not use this function; it is broken on platforms where the %char
+ * type is unsigned, such as ARM and PowerPC.  See g_value_get_schar().
+ *
+ * Get the contents of a %G_TYPE_CHAR #GValue.  
  * 
  * Returns: character contents of @value
+ * Deprecated: 2.32: This function's return type is broken, see g_value_get_schar()
  */
 gchar
 g_value_get_char (const GValue *value)
@@ -663,6 +668,41 @@ g_value_get_char (const GValue *value)
 }
 
 /**
+ * g_value_set_schar:
+ * @value: a valid #GValue of type %G_TYPE_CHAR
+ * @v_char: signed 8 bit integer to be set
+ *
+ * Set the contents of a %G_TYPE_CHAR #GValue to @v_char.
+ *
+ * Since: 2.32
+ */
+void
+g_value_set_schar (GValue *value,
+		   gint8   v_char)
+{
+  g_return_if_fail (G_VALUE_HOLDS_CHAR (value));
+  
+  value->data[0].v_int = v_char;
+}
+
+/**
+ * g_value_get_schar:
+ * @value: a valid #GValue of type %G_TYPE_CHAR
+ *
+ * Get the contents of a %G_TYPE_CHAR #GValue.
+ * 
+ * Returns: signed 8 bit integer contents of @value
+ * Since: 2.32
+ */
+gint8
+g_value_get_schar (const GValue *value)
+{
+  g_return_val_if_fail (G_VALUE_HOLDS_CHAR (value), 0);
+  
+  return value->data[0].v_int;
+}
+
+/**
  * g_value_set_uchar:
  * @value: a valid #GValue of type %G_TYPE_UCHAR
  * @v_uchar: unsigned character value to be set
diff --git a/gobject/gvaluetypes.h b/gobject/gvaluetypes.h
index 972c868..a7c2414 100644
--- a/gobject/gvaluetypes.h
+++ b/gobject/gvaluetypes.h
@@ -177,9 +177,14 @@ G_BEGIN_DECLS
 
 
 /* --- prototypes --- */
+#ifndef G_DISABLE_DEPRECATED
 void		      g_value_set_char		(GValue	      *value,
 						 gchar	       v_char);
 gchar		      g_value_get_char		(const GValue *value);
+#endif
+void		      g_value_set_schar		(GValue	      *value,
+						 gint8	       v_char);
+gint8		      g_value_get_schar		(const GValue *value);
 void		      g_value_set_uchar		(GValue	      *value,
 						 guchar	       v_uchar);
 guchar		      g_value_get_uchar		(const GValue *value);
diff --git a/gobject/tests/param.c b/gobject/tests/param.c
index 53d5159..d06bd51 100644
--- a/gobject/tests/param.c
+++ b/gobject/tests/param.c
@@ -145,8 +145,15 @@ test_value_transform (void)
   g_value_unset (&src);                                                 \
   g_value_unset (&dest);
 
-  CHECK_INT_CONVERSION(G_TYPE_CHAR, char, -124)
+  /* Keep a check for an integer in the range of 0-127 so we're
+   * still testing g_value_get_char().  See
+   * https://bugzilla.gnome.org/show_bug.cgi?id=659870
+   * for why it is broken.
+   */
   CHECK_INT_CONVERSION(G_TYPE_CHAR, char, 124)
+
+  CHECK_INT_CONVERSION(G_TYPE_CHAR, schar, -124)
+  CHECK_INT_CONVERSION(G_TYPE_CHAR, schar, 124)
   CHECK_INT_CONVERSION(G_TYPE_UCHAR, uchar, 0)
   CHECK_INT_CONVERSION(G_TYPE_UCHAR, uchar, 255)
   CHECK_INT_CONVERSION(G_TYPE_INT, int, -12345)
@@ -378,9 +385,9 @@ test_value_transform (void)
   g_value_init (&src, G_TYPE_STRING);
   g_value_init (&dest, G_TYPE_CHAR);
   g_value_set_static_string (&src, "bla");
-  g_value_set_char (&dest, 'c');
+  g_value_set_schar (&dest, 'c');
   g_assert (!g_value_transform (&src, &dest));
-  g_assert_cmpint (g_value_get_char (&dest), ==, 'c');
+  g_assert_cmpint (g_value_get_schar (&dest), ==, 'c');
   g_value_unset (&src);
   g_value_unset (&dest);
 }
diff --git a/tests/gobject/gvalue-test.c b/tests/gobject/gvalue-test.c
index 516a484..bec3c64 100644
--- a/tests/gobject/gvalue-test.c
+++ b/tests/gobject/gvalue-test.c
@@ -50,6 +50,7 @@ test_enum_transformation (void)
  g_value_init (&xform, G_TYPE_CHAR); 
  g_value_transform (&orig, &xform); 
  g_assert (g_value_get_char (&xform) == 1);
+ g_assert (g_value_get_schar (&xform) == 1);
 
  memset (&xform, 0, sizeof (GValue));
  g_value_init (&xform, G_TYPE_UCHAR); 
diff --git a/tests/gobject/paramspec-test.c b/tests/gobject/paramspec-test.c
index 6de850f..d09945b 100644
--- a/tests/gobject/paramspec-test.c
+++ b/tests/gobject/paramspec-test.c
@@ -67,6 +67,22 @@ test_param_spec_char (void)
   modified = g_param_value_validate (pspec, &value);
   g_assert (modified && g_value_get_char (&value) == 40);
 
+  g_value_set_schar (&value, 0);
+  modified = g_param_value_validate (pspec, &value);
+  g_assert (modified && g_value_get_schar (&value) == 20);
+
+  g_value_set_schar (&value, 20);
+  modified = g_param_value_validate (pspec, &value);
+  g_assert (!modified && g_value_get_schar (&value) == 20);
+
+  g_value_set_schar (&value, 40);
+  modified = g_param_value_validate (pspec, &value);
+  g_assert (!modified && g_value_get_schar (&value) == 40);
+
+  g_value_set_schar (&value, 60);
+  modified = g_param_value_validate (pspec, &value);
+  g_assert (modified && g_value_get_schar (&value) == 40);
+
   g_param_spec_unref (pspec);
 }
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]