summaryrefslogtreecommitdiff
path: root/girepository
diff options
context:
space:
mode:
authorOwen W. Taylor <otaylor@fishsoup.net>2010-09-14 11:59:03 -0400
committerOwen W. Taylor <otaylor@fishsoup.net>2010-11-01 17:25:45 -0400
commit8916db0a3831cb5e6c3b714125f7596f43d6aa6a (patch)
treec4d523a925a666be85bfdaea804407ca782778f7 /girepository
parent29ec4294d9232dcfd7cfec4e20c0e302a5ff3e80 (diff)
downloadgobject-introspection-8916db0a3831cb5e6c3b714125f7596f43d6aa6a.tar.gz
Handle enumerations with the full range of signed and unsigned values
The C compiler will pick an enumeration type that accomodates the specified values for the enumeration, so ignoring 64-bit enumerations, we can have enumeration values from MININT32 to MAXUINT32. To handle this properly: - Use gint64 for holding eumeration values when scanning - Add a 'unsigned_value' bit to ValueBlob so we can distinguish the int32 vs. uint32 cases in the typelib - Change the return value of g_value_info_get_value() to gint64. https://bugzilla.gnome.org/show_bug.cgi?id=629704
Diffstat (limited to 'girepository')
-rw-r--r--girepository/gienuminfo.c11
-rw-r--r--girepository/gienuminfo.h2
-rw-r--r--girepository/gifieldinfo.c6
-rw-r--r--girepository/girnode.c3
-rw-r--r--girepository/girnode.h2
-rw-r--r--girepository/girparser.c10
-rw-r--r--girepository/girwriter.c7
-rw-r--r--girepository/gitypelib-internal.h4
8 files changed, 28 insertions, 17 deletions
diff --git a/girepository/gienuminfo.c b/girepository/gienuminfo.c
index 9ecbc2ab..062f3abf 100644
--- a/girepository/gienuminfo.c
+++ b/girepository/gienuminfo.c
@@ -127,9 +127,11 @@ g_enum_info_get_storage_type (GIEnumInfo *info)
*
* Obtain the enumeration value of the #GIValueInfo.
*
- * Returns: the enumeration value
+ * Returns: the enumeration value. This will always be representable
+ * as a 32-bit signed or unsigned value. The use of gint64 as the
+ * return type is to allow both.
*/
-glong
+gint64
g_value_info_get_value (GIValueInfo *info)
{
GIRealInfo *rinfo = (GIRealInfo *)info;
@@ -140,6 +142,9 @@ g_value_info_get_value (GIValueInfo *info)
blob = (ValueBlob *)&rinfo->typelib->data[rinfo->offset];
- return (glong)blob->value;
+ if (blob->unsigned_value)
+ return (gint64)(guint32)blob->value;
+ else
+ return (gint64)blob->value;
}
diff --git a/girepository/gienuminfo.h b/girepository/gienuminfo.h
index 211ea6ef..6b24fe7e 100644
--- a/girepository/gienuminfo.h
+++ b/girepository/gienuminfo.h
@@ -42,7 +42,7 @@ GIValueInfo * g_enum_info_get_value (GIEnumInfo *info,
gint n);
GITypeTag g_enum_info_get_storage_type (GIEnumInfo *info);
-glong g_value_info_get_value (GIValueInfo *info);
+gint64 g_value_info_get_value (GIValueInfo *info);
G_END_DECLS
diff --git a/girepository/gifieldinfo.c b/girepository/gifieldinfo.c
index 21a6db02..1a6b688c 100644
--- a/girepository/gifieldinfo.c
+++ b/girepository/gifieldinfo.c
@@ -269,9 +269,9 @@ g_field_info_get_field (GIFieldInfo *field_info,
case GI_INFO_TYPE_FLAGS:
{
/* FIXME: there's a mismatch here between the value->v_int we use
- * here and the glong result returned from g_value_info_get_value().
- * But to switch this to glong, we'd have to make g_function_info_invoke()
- * translate value->v_long to the proper ABI for an enum function
+ * here and the gint64 result returned from g_value_info_get_value().
+ * But to switch this to gint64, we'd have to make g_function_info_invoke()
+ * translate value->v_int64 to the proper ABI for an enum function
* call parameter, which will usually be int, and then fix up language
* bindings.
*/
diff --git a/girepository/girnode.c b/girepository/girnode.c
index 46fd3c7d..5b9df585 100644
--- a/girepository/girnode.c
+++ b/girepository/girnode.c
@@ -2201,8 +2201,9 @@ g_ir_node_build_typelib (GIrNode *node,
blob->deprecated = value->deprecated;
blob->reserved = 0;
+ blob->unsigned_value = value->value >= 0 ? 1 : 0;
blob->name = write_string (node->name, strings, data, offset2);
- blob->value = value->value;
+ blob->value = (gint32)value->value;
}
break;
diff --git a/girepository/girnode.h b/girepository/girnode.h
index edb94008..0df10088 100644
--- a/girepository/girnode.h
+++ b/girepository/girnode.h
@@ -262,7 +262,7 @@ struct _GIrNodeValue
gboolean deprecated;
- gint32 value;
+ gint64 value;
};
struct _GIrNodeConstant
diff --git a/girepository/girparser.c b/girepository/girparser.c
index 8f8f6f4d..42525ecd 100644
--- a/girepository/girparser.c
+++ b/girepository/girparser.c
@@ -1440,7 +1440,7 @@ start_property (GMarkupParseContext *context,
return TRUE;
}
-static gint
+static gint64
parse_value (const gchar *str)
{
gchar *shift_op;
@@ -1450,15 +1450,15 @@ parse_value (const gchar *str)
if (shift_op)
{
- gint base, shift;
+ gint64 base, shift;
- base = strtol (str, NULL, 10);
- shift = strtol (shift_op + 3, NULL, 10);
+ base = g_ascii_strtoll (str, NULL, 10);
+ shift = g_ascii_strtoll (shift_op + 3, NULL, 10);
return base << shift;
}
else
- return strtol (str, NULL, 10);
+ return g_ascii_strtoll (str, NULL, 10);
return 0;
}
diff --git a/girepository/girwriter.c b/girepository/girwriter.c
index 8c4fa2c3..e90799c1 100644
--- a/girepository/girwriter.c
+++ b/girepository/girwriter.c
@@ -704,7 +704,8 @@ write_value_info (const gchar *namespace,
Xml *file)
{
const gchar *name;
- glong value;
+ gint64 value;
+ gchar *value_str;
gboolean deprecated;
name = g_base_info_get_name ((GIBaseInfo *)info);
@@ -712,7 +713,9 @@ write_value_info (const gchar *namespace,
deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
xml_start_element (file, "member");
- xml_printf (file, " name=\"%s\" value=\"%ld\"", name, value);
+ value_str = g_strdup_printf ("%" G_GINT64_FORMAT, value);
+ xml_printf (file, " name=\"%s\" value=\"%s\"", name, value_str);
+ g_free (value_str);
if (deprecated)
xml_printf (file, " deprecated=\"1\"");
diff --git a/girepository/gitypelib-internal.h b/girepository/gitypelib-internal.h
index 26fd6bfb..de2f131b 100644
--- a/girepository/gitypelib-internal.h
+++ b/girepository/gitypelib-internal.h
@@ -632,6 +632,7 @@ typedef struct {
/**
* ValueBlob:
* @deprecated: Whether this value is deprecated
+ * @unsigned_value: if set, value is a 32-bit unsigned integer cast to gint32
* @value: The numerical value
* @name: Name of blob
*
@@ -639,8 +640,9 @@ typedef struct {
*/
typedef struct {
guint32 deprecated : 1;
+ guint32 unsigned_value : 1;
/* <private> */
- guint32 reserved :31;
+ guint32 reserved :30;
/* <public> */
guint32 name;
gint32 value;