gobject-introspection r214 - in trunk: . girepository tests tests/invoke tools
- From: johan svn gnome org
- To: svn-commits-list gnome org
- Subject: gobject-introspection r214 - in trunk: . girepository tests tests/invoke tools
- Date: Tue, 22 Apr 2008 23:48:17 +0100 (BST)
Author: johan
Date: Tue Apr 22 22:48:16 2008
New Revision: 214
URL: http://svn.gnome.org/viewvc/gobject-introspection?rev=214&view=rev
Log:
2008-04-22 Johan Dahlin <johan gnome org>
* girepository/ginfo.c (g_info_from_entry), (g_type_info_new),
(g_type_info_is_pointer), (g_type_info_get_tag),
(g_type_info_get_param_type), (g_type_info_get_interface),
(g_type_info_get_array_length), (g_type_info_is_zero_terminated),
(g_type_info_get_n_error_domains), (g_type_info_get_error_domain),
(g_error_domain_info_get_codes), (g_enum_info_get_value),
(g_object_info_get_interface), (g_object_info_get_field),
(g_interface_info_get_prerequisite),
(g_signal_info_get_class_closure), (g_constant_info_get_value):
* girepository/ginvoke.c (get_ffi_type):
* girepository/girepository.h:
* girepository/gmetadata.c (g_metadata_get_dir_entry),
(g_metadata_check_sanity), (validate_header),
(validate_array_type_blob), (validate_iface_type_blob),
(validate_param_type_blob), (validate_error_type_blob),
(validate_type_blob), (validate_constant_blob),
(validate_struct_blob), (validate_enum_blob):
* girepository/gmetadata.h:
* tests/Makefile.am:
* tests/invoke/Makefile.am:
* tests/invoke/invoke.c (main):
* tests/roundtrips.sh:
* tools/Makefile.am:
* tools/compiler.c (format_output), (write_out_metadata), (main):
* tools/generate.c (write_type_name), (write_type_info),
(write_constant_value), (write_enum_info), (load_metadata), (main):
* tools/gidlcompilercontext.c:
* tools/gidlcompilercontext.h:
* tools/gidlcompilerentrynode.c:
* tools/gidlcompilerentrynode.h:
* tools/gidlcompilertypenode.c:
* tools/gidlcompilertypenode.h:
* tools/gidlmodule.c (g_idl_module_build_metadata):
* tools/gidlmodule.h:
* tools/gidlnode.c (init_stats), (dump_stats),
(g_idl_node_get_size), (g_idl_node_get_full_size),
(g_idl_node_cmp), (g_idl_node_can_have_member),
(g_idl_node_add_member), (g_idl_node_param_direction_string),
(parse_int_value), (parse_uint_value), (parse_float_value),
(parse_boolean_value), (find_entry_node), (find_entry),
(serialize_type), (g_idl_node_build_metadata), (write_string):
* tools/gidlnode.h:
* tools/gidlparser.c (parse_type_internal):
* tools/quote-file.sh:
Revert revisions 157,149-148,136-129 and 120.
Move back to using g-idl-generate to generate the metadata and
avoids dependency on a c compiler.
Added:
trunk/tests/invoke/invoke-namespace-find.sh
- copied unchanged from r119, /trunk/tests/invoke/invoke-namespace-find.sh
Removed:
trunk/tools/gidlcompilercontext.c
trunk/tools/gidlcompilercontext.h
trunk/tools/gidlcompilerentrynode.c
trunk/tools/gidlcompilerentrynode.h
trunk/tools/gidlcompilertypenode.c
trunk/tools/gidlcompilertypenode.h
trunk/tools/quote-file.sh
Modified:
trunk/ChangeLog
trunk/girepository/ginfo.c
trunk/girepository/ginvoke.c
trunk/girepository/girepository.h
trunk/girepository/gmetadata.c
trunk/girepository/gmetadata.h
trunk/tests/Makefile.am
trunk/tests/invoke/Makefile.am
trunk/tests/invoke/invoke.c
trunk/tests/roundtrips.sh
trunk/tools/Makefile.am
trunk/tools/compiler.c
trunk/tools/generate.c
trunk/tools/gidlmodule.c
trunk/tools/gidlmodule.h
trunk/tools/gidlnode.c
trunk/tools/gidlnode.h
trunk/tools/gidlparser.c
Modified: trunk/girepository/ginfo.c
==============================================================================
--- trunk/girepository/ginfo.c (original)
+++ trunk/girepository/ginfo.c Tue Apr 22 22:48:16 2008
@@ -161,35 +161,29 @@
{
GIBaseInfo *result;
DirEntry *entry = g_metadata_get_dir_entry (metadata, index);
-
+
if (entry->local)
result = g_info_new (entry->blob_type, NULL, metadata, entry->offset);
- else
+ else
{
- const gchar *namespace = NULL;
- const gchar *name = NULL;
+ const gchar *namespace = g_metadata_get_string (metadata, entry->offset);
+ const gchar *name = g_metadata_get_string (metadata, entry->name);
+
GIRepository *repository = g_irepository_get_default ();
-
- namespace = g_metadata_get_string (metadata, entry->offset);
- name = g_metadata_get_string (metadata, entry->name);
-
+
result = g_irepository_find_by_name (repository, namespace, name);
if (result == NULL)
{
GIUnresolvedInfo *unresolved;
+
unresolved = g_new0 (GIUnresolvedInfo, 1);
+
unresolved->type = GI_INFO_TYPE_UNRESOLVED;
unresolved->ref_count = 1;
unresolved->container = NULL;
unresolved->name = name;
- if (entry->offset)
- {
- unresolved->namespace = namespace;
- }
- else
- {
- unresolved->namespace = NULL;
- }
+ unresolved->namespace = namespace;
+
result = (GIBaseInfo*)unresolved;
}
}
@@ -534,27 +528,15 @@
return 0;
}
-/* Type blobs when created always point to a SimpleTypeBlob,
- * If the type tag means that the type needs to be complex then
- * the SimpleTypeBlob has an offset which points to the real type.
- */
GITypeInfo *
g_type_info_new (GIBaseInfo *container,
GMetadata *metadata,
guint32 offset)
{
- TypeHeader *header;
- SimpleTypeBlob *simple;
-
- header = (TypeHeader *)&metadata->data[offset];
- if (TYPE_IS_COMPLEX (header->tag))
- {
- simple = (SimpleTypeBlob *)&metadata->data[offset];
- offset = simple->offset;
- }
+ SimpleTypeBlob *type = (SimpleTypeBlob *)&metadata->data[offset];
- return (GITypeInfo*)g_info_new (GI_INFO_TYPE_TYPE, container,
- metadata, offset);
+ return (GITypeInfo *) g_info_new (GI_INFO_TYPE_TYPE, container, metadata,
+ type->reserved == 0 ? offset : type->offset);
}
/**
@@ -739,18 +721,32 @@
g_type_info_is_pointer (GITypeInfo *info)
{
GIBaseInfo *base = (GIBaseInfo *)info;
- TypeHeader *header = (TypeHeader *)&base->metadata->data[base->offset];
-
- return header->pointer != 0;
+ SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset];
+
+ if (type->reserved == 0)
+ return type->pointer;
+ else
+ {
+ InterfaceTypeBlob *iface = (InterfaceTypeBlob *)&base->metadata->data[base->offset];
+
+ return iface->pointer;
+ }
}
GITypeTag
g_type_info_get_tag (GITypeInfo *info)
{
GIBaseInfo *base = (GIBaseInfo *)info;
- TypeHeader *header = (TypeHeader *)&base->metadata->data[base->offset];
+ SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset];
+
+ if (type->reserved == 0)
+ return type->tag;
+ else
+ {
+ InterfaceTypeBlob *iface = (InterfaceTypeBlob *)&base->metadata->data[base->offset];
- return header->tag;
+ return iface->tag;
+ }
}
GITypeInfo *
@@ -758,39 +754,42 @@
gint n)
{
GIBaseInfo *base = (GIBaseInfo *)info;
- TypeHeader *header = (TypeHeader *)&base->metadata->data[base->offset];
- ParamTypeBlob *param = (ParamTypeBlob *)&base->metadata->data[base->offset];
-
- switch (header->tag)
+ SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset];
+
+ if (type->reserved != 0)
{
- case TYPE_TAG_ARRAY:
- case TYPE_TAG_LIST:
- case TYPE_TAG_SLIST:
- case TYPE_TAG_HASH:
- {
- guint32 offset = base->offset + sizeof(ParamTypeBlob) +
- (sizeof(SimpleTypeBlob)* n);
- return g_type_info_new (base, base->metadata, offset);
- }
- default:
- return NULL;
- }
+ ParamTypeBlob *param = (ParamTypeBlob *)&base->metadata->data[base->offset];
- g_assert_not_reached ();
+ switch (param->tag)
+ {
+ case GI_TYPE_TAG_ARRAY:
+ case GI_TYPE_TAG_GLIST:
+ case GI_TYPE_TAG_GSLIST:
+ case GI_TYPE_TAG_GHASH:
+ return g_type_info_new (base, base->metadata, base->offset + 4 + 4 * n);
+ break;
+
+ default: ;
+ }
+ }
+
+ return NULL;
}
GIBaseInfo *
g_type_info_get_interface (GITypeInfo *info)
{
GIBaseInfo *base = (GIBaseInfo *)info;
- TypeHeader *header = (TypeHeader *)&base->metadata->data[base->offset];
- SimpleTypeBlob *simple = (SimpleTypeBlob *)&base->metadata->data[base->offset];
-
- if (header->tag == TYPE_TAG_SYMBOL)
+ SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset];
+
+ if (type->reserved != 0)
{
- CommonBlob *common = (CommonBlob *)&base->metadata->data[simple->offset];
- return g_info_from_entry (base->metadata, simple->offset);
+ InterfaceTypeBlob *blob = (InterfaceTypeBlob *)&base->metadata->data[base->offset];
+
+ if (blob->tag == GI_TYPE_TAG_INTERFACE)
+ return g_info_from_entry (base->metadata, blob->interface);
}
+
return NULL;
}
@@ -798,13 +797,19 @@
g_type_info_get_array_length (GITypeInfo *info)
{
GIBaseInfo *base = (GIBaseInfo *)info;
- TypeHeader *header = (TypeHeader *)&base->metadata->data[base->offset];
- ArrayTypeBlob *array = (ArrayTypeBlob *)&base->metadata->data[base->offset];
-
- if (header->tag == TYPE_TAG_ARRAY && array->has_length)
+ SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset];
+
+ if (type->reserved != 0)
{
- return array->length;
+ ArrayTypeBlob *blob = (ArrayTypeBlob *)&base->metadata->data[base->offset];
+
+ if (blob->tag == GI_TYPE_TAG_ARRAY)
+ {
+ if (blob->has_length)
+ return blob->length;
+ }
}
+
return -1;
}
@@ -812,24 +817,33 @@
g_type_info_is_zero_terminated (GITypeInfo *info)
{
GIBaseInfo *base = (GIBaseInfo *)info;
- TypeHeader *header = (TypeHeader *)&base->metadata->data[base->offset];
- ArrayTypeBlob *array = (ArrayTypeBlob *)&base->metadata->data[base->offset];
+ SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset];
+
+ if (type->reserved != 0)
+ {
+ ArrayTypeBlob *blob = (ArrayTypeBlob *)&base->metadata->data[base->offset];
- return (header->tag == TYPE_TAG_ARRAY &&
- array->zero_terminated);
+ if (blob->tag == GI_TYPE_TAG_ARRAY)
+ return blob->zero_terminated;
+ }
+
+ return FALSE;
}
gint
g_type_info_get_n_error_domains (GITypeInfo *info)
{
GIBaseInfo *base = (GIBaseInfo *)info;
- TypeHeader *header = (TypeHeader *)&base->metadata->data[base->offset];
- ErrorTypeBlob *error = (ErrorTypeBlob *)&base->metadata->data[base->offset];
-
- if (header->tag == TYPE_TAG_ERROR)
+ SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset];
+
+ if (type->reserved != 0)
{
- return error->n_domains;
+ ErrorTypeBlob *blob = (ErrorTypeBlob *)&base->metadata->data[base->offset];
+
+ if (blob->tag == GI_TYPE_TAG_ERROR)
+ return blob->n_domains;
}
+
return 0;
}
@@ -838,16 +852,17 @@
gint n)
{
GIBaseInfo *base = (GIBaseInfo *)info;
- TypeHeader *header = (TypeHeader *)&base->metadata->data[base->offset];
- ErrorTypeBlob *error = (ErrorTypeBlob *)&base->metadata->data[base->offset];
- guint16 *domain;
-
- if (header->tag == TYPE_TAG_ERROR)
+ SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset];
+
+ if (type->reserved != 0)
{
- domain = (guint16*) (&base->metadata->data[base->offset + sizeof(ErrorTypeBlob)]);
- return (GIErrorDomainInfo *) g_info_from_entry (base->metadata,
- domain[n]);
+ ErrorTypeBlob *blob = (ErrorTypeBlob *)&base->metadata->data[base->offset];
+
+ if (blob->tag == GI_TYPE_TAG_ERROR)
+ return (GIErrorDomainInfo *) g_info_from_entry (base->metadata,
+ blob->domains[n]);
}
+
return NULL;
}
@@ -866,13 +881,9 @@
g_error_domain_info_get_codes (GIErrorDomainInfo *info)
{
GIBaseInfo *base = (GIBaseInfo *)info;
- ErrorDomainBlob *blob = (ErrorDomainBlob *)&base->metadata->data[base->offset];
-
- /* FIXME need to check if blob really is an enum */
- return (GIInterfaceInfo *) g_info_new (BLOB_TYPE_ENUM,
- NULL,
- base->metadata,
- blob->error_codes);
+ ErrorDomainBlob *blob = (ErrorDomainBlob *)&base->metadata->data[base->offset];
+
+ return (GIInterfaceInfo *) g_info_from_entry (base->metadata, blob->error_codes);
}
@@ -999,8 +1010,8 @@
gint offset;
offset = base->offset + header->struct_blob_size
- + blob->n_fields * header->field_blob_size
- + n * header->function_blob_size;
+ + blob->n_fields * header->field_blob_size
+ + n * header->function_blob_size;
return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, base,
base->metadata, offset);
}
@@ -1054,15 +1065,6 @@
return blob->n_values;
}
-gboolean
-g_enum_info_is_registered (GIEnumInfo *info)
-{
- GIBaseInfo *base = (GIBaseInfo *)info;
- EnumBlob *blob = (EnumBlob *)&base->metadata->data[base->offset];
-
- return !blob->unregistered;
-}
-
GIValueInfo *
g_enum_info_get_value (GIEnumInfo *info,
gint n)
@@ -1073,8 +1075,7 @@
offset = base->offset + header->enum_blob_size
+ n * header->value_blob_size;
- return (GIValueInfo *) g_info_new (GI_INFO_TYPE_VALUE, base,
- base->metadata, offset);
+ return (GIValueInfo *) g_info_new (GI_INFO_TYPE_VALUE, base, base->metadata, offset);
}
/* GIObjectInfo functions */
@@ -1123,11 +1124,8 @@
{
GIBaseInfo *base = (GIBaseInfo *)info;
ObjectBlob *blob = (ObjectBlob *)&base->metadata->data[base->offset];
- guint16 *interface;
- interface = (guint16 *)&base->metadata->data[base->offset + sizeof(ObjectBlob)];
-
- return (GIInterfaceInfo *) g_info_from_entry (base->metadata, interface[n]);
+ return (GIInterfaceInfo *) g_info_from_entry (base->metadata, blob->interfaces[n]);
}
gint
@@ -1152,8 +1150,7 @@
+ (blob->n_interfaces + blob->n_interfaces % 2) * 2
+ n * header->field_blob_size;
- return (GIFieldInfo *) g_info_new (GI_INFO_TYPE_FIELD, base,
- base->metadata, offset);
+ return (GIFieldInfo *) g_info_new (GI_INFO_TYPE_FIELD, base, base->metadata, offset);
}
gint
@@ -1335,11 +1332,8 @@
{
GIBaseInfo *base = (GIBaseInfo *)info;
InterfaceBlob *blob = (InterfaceBlob *)&base->metadata->data[base->offset];
- guint16 *prerequisite;
-
- prerequisite = (guint16 *)&base->metadata->data[base->offset + sizeof(InterfaceBlob)];
- return g_info_from_entry (base->metadata, prerequisite[n]);
+ return g_info_from_entry (base->metadata, blob->prerequisites[n]);
}
@@ -1578,8 +1572,7 @@
SignalBlob *blob = (SignalBlob *)&base->metadata->data[base->offset];
if (blob->has_class_closure)
- return g_interface_info_get_vfunc ((GIInterfaceInfo *)base->container,
- blob->class_closure);
+ return g_interface_info_get_vfunc ((GIInterfaceInfo *)base->container, blob->class_closure);
return NULL;
}
@@ -1653,67 +1646,63 @@
{
GIBaseInfo *base = (GIBaseInfo *)info;
ConstantBlob *blob = (ConstantBlob *)&base->metadata->data[base->offset];
- TypeHeader *header = (TypeHeader*) &blob->type;
- if (TYPE_IS_SIMPLE (header->tag))
- {
- switch (header->tag)
- {
- case GI_TYPE_TAG_BOOLEAN:
- value->v_boolean = *(gboolean*)&base->metadata->data[blob->offset];
- break;
- case GI_TYPE_TAG_INT8:
- value->v_int8 = *(gint8*)&base->metadata->data[blob->offset];
- break;
- case GI_TYPE_TAG_UINT8:
- value->v_uint8 = *(guint8*)&base->metadata->data[blob->offset];
- break;
- case GI_TYPE_TAG_INT16:
- value->v_int16 = *(gint16*)&base->metadata->data[blob->offset];
- break;
- case GI_TYPE_TAG_UINT16:
- value->v_uint16 = *(guint16*)&base->metadata->data[blob->offset];
- break;
- case GI_TYPE_TAG_INT32:
- value->v_int32 = *(gint32*)&base->metadata->data[blob->offset];
- break;
- case GI_TYPE_TAG_UINT32:
- value->v_uint32 = *(guint32*)&base->metadata->data[blob->offset];
- break;
- case GI_TYPE_TAG_INT64:
- value->v_int64 = *(gint64*)&base->metadata->data[blob->offset];
- break;
- case GI_TYPE_TAG_UINT64:
- value->v_uint64 = *(guint64*)&base->metadata->data[blob->offset];
- break;
- case GI_TYPE_TAG_FLOAT:
- value->v_float = *(gfloat*)&base->metadata->data[blob->offset];
- break;
- case GI_TYPE_TAG_DOUBLE:
- value->v_double = *(gdouble*)&base->metadata->data[blob->offset];
- break;
- case GI_TYPE_TAG_INT:
- value->v_int = *(gint*)&base->metadata->data[blob->offset];
- break;
- case GI_TYPE_TAG_UINT:
- value->v_uint = *(guint*)&base->metadata->data[blob->offset];
- break;
- case GI_TYPE_TAG_LONG:
- value->v_long = *(glong*)&base->metadata->data[blob->offset];
- break;
- case GI_TYPE_TAG_ULONG:
- value->v_ulong = *(gulong*)&base->metadata->data[blob->offset];
- break;
- }
- }
- else
+ /* FIXME non-basic types ? */
+ if (blob->type.reserved == 0)
{
- switch (header->tag)
- {
- case GI_TYPE_TAG_SYMBOL:
- value->v_string = *(gchar**)&base->metadata->data[blob->offset];
- break;
- }
+ if (blob->type.pointer)
+ value->v_pointer = g_memdup (&base->metadata->data[blob->offset], blob->size);
+ else
+ {
+ switch (blob->type.tag)
+ {
+ case GI_TYPE_TAG_BOOLEAN:
+ value->v_boolean = *(gboolean*)&base->metadata->data[blob->offset];
+ break;
+ case GI_TYPE_TAG_INT8:
+ value->v_int8 = *(gint8*)&base->metadata->data[blob->offset];
+ break;
+ case GI_TYPE_TAG_UINT8:
+ value->v_uint8 = *(guint8*)&base->metadata->data[blob->offset];
+ break;
+ case GI_TYPE_TAG_INT16:
+ value->v_int16 = *(gint16*)&base->metadata->data[blob->offset];
+ break;
+ case GI_TYPE_TAG_UINT16:
+ value->v_uint16 = *(guint16*)&base->metadata->data[blob->offset];
+ break;
+ case GI_TYPE_TAG_INT32:
+ value->v_int32 = *(gint32*)&base->metadata->data[blob->offset];
+ break;
+ case GI_TYPE_TAG_UINT32:
+ value->v_uint32 = *(guint32*)&base->metadata->data[blob->offset];
+ break;
+ case GI_TYPE_TAG_INT64:
+ value->v_int64 = *(gint64*)&base->metadata->data[blob->offset];
+ break;
+ case GI_TYPE_TAG_UINT64:
+ value->v_uint64 = *(guint64*)&base->metadata->data[blob->offset];
+ break;
+ case GI_TYPE_TAG_FLOAT:
+ value->v_float = *(gfloat*)&base->metadata->data[blob->offset];
+ break;
+ case GI_TYPE_TAG_DOUBLE:
+ value->v_double = *(gdouble*)&base->metadata->data[blob->offset];
+ break;
+ case GI_TYPE_TAG_INT:
+ value->v_int = *(gint*)&base->metadata->data[blob->offset];
+ break;
+ case GI_TYPE_TAG_UINT:
+ value->v_uint = *(guint*)&base->metadata->data[blob->offset];
+ break;
+ case GI_TYPE_TAG_LONG:
+ value->v_long = *(glong*)&base->metadata->data[blob->offset];
+ break;
+ case GI_TYPE_TAG_ULONG:
+ value->v_ulong = *(gulong*)&base->metadata->data[blob->offset];
+ break;
+ }
+ }
}
return blob->size;
@@ -1814,4 +1803,4 @@
}
return NULL;
-}
+}
Modified: trunk/girepository/ginvoke.c
==============================================================================
--- trunk/girepository/ginvoke.c (original)
+++ trunk/girepository/ginvoke.c Tue Apr 22 22:48:16 2008
@@ -100,8 +100,8 @@
break;
case GI_TYPE_TAG_UTF8:
case GI_TYPE_TAG_FILENAME:
- case GI_TYPE_TAG_SYMBOL:
case GI_TYPE_TAG_ARRAY:
+ case GI_TYPE_TAG_INTERFACE:
case GI_TYPE_TAG_GLIST:
case GI_TYPE_TAG_GSLIST:
case GI_TYPE_TAG_GHASH:
Modified: trunk/girepository/girepository.h
==============================================================================
--- trunk/girepository/girepository.h (original)
+++ trunk/girepository/girepository.h Tue Apr 22 22:48:16 2008
@@ -277,8 +277,8 @@
GI_TYPE_TAG_DOUBLE = 17,
GI_TYPE_TAG_UTF8 = 18,
GI_TYPE_TAG_FILENAME = 19,
- GI_TYPE_TAG_SYMBOL = 20,
- GI_TYPE_TAG_ARRAY = 21,
+ GI_TYPE_TAG_ARRAY = 20,
+ GI_TYPE_TAG_INTERFACE = 21,
GI_TYPE_TAG_GLIST = 22,
GI_TYPE_TAG_GSLIST = 23,
GI_TYPE_TAG_GHASH = 24,
@@ -355,7 +355,6 @@
/* GIEnumInfo */
gint g_enum_info_get_n_values (GIEnumInfo *info);
-gboolean g_enum_info_get_is_registered (GIEnumInfo *info);
GIValueInfo * g_enum_info_get_value (GIEnumInfo *info,
gint n);
Modified: trunk/girepository/gmetadata.c
==============================================================================
--- trunk/girepository/gmetadata.c (original)
+++ trunk/girepository/gmetadata.c Tue Apr 22 22:48:16 2008
@@ -30,11 +30,6 @@
#define ALIGN_VALUE(this, boundary) \
(( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1)))
-static gboolean
-validate_blob (GMetadata *metadata,
- guint32 offset,
- GError **error);
-
DirEntry *
g_metadata_get_dir_entry (GMetadata *metadata,
@@ -42,9 +37,41 @@
{
Header *header = (Header *)metadata->data;
- return (DirEntry *)&metadata->data[header->directory + ((index - 1) * header->entry_blob_size)];
+ return (DirEntry *)&metadata->data[header->directory + (index - 1) * header->entry_blob_size];
}
+void
+g_metadata_check_sanity (void)
+{
+ /* Check that struct layout is as we expect */
+ g_assert (sizeof (Header) == 100);
+ g_assert (sizeof (DirEntry) == 12);
+ g_assert (sizeof (SimpleTypeBlob) == 4);
+ g_assert (sizeof (ArgBlob) == 12);
+ g_assert (sizeof (SignatureBlob) == 8);
+ g_assert (sizeof (CommonBlob) == 8);
+ g_assert (sizeof (FunctionBlob) == 16);
+ g_assert (sizeof (InterfaceTypeBlob) == 4);
+ g_assert (sizeof (ArrayTypeBlob) == 8);
+ g_assert (sizeof (ParamTypeBlob) == 4);
+ g_assert (sizeof (ErrorTypeBlob) == 4);
+ g_assert (sizeof (ErrorDomainBlob) == 16);
+ g_assert (sizeof (ValueBlob) == 12);
+ g_assert (sizeof (FieldBlob) == 12);
+ g_assert (sizeof (RegisteredTypeBlob) == 16);
+ g_assert (sizeof (StructBlob) == 20);
+ g_assert (sizeof (EnumBlob) == 20);
+ g_assert (sizeof (PropertyBlob) == 12);
+ g_assert (sizeof (SignalBlob) == 12);
+ g_assert (sizeof (VFuncBlob) == 16);
+ g_assert (sizeof (ObjectBlob) == 32);
+ g_assert (sizeof (InterfaceBlob) == 28);
+ g_assert (sizeof (ConstantBlob) == 20);
+ g_assert (sizeof (AnnotationBlob) == 12);
+ g_assert (sizeof (UnionBlob) == 28);
+}
+
+
static gboolean
is_aligned (guint32 offset)
{
@@ -124,6 +151,32 @@
return FALSE;
}
+ if (header->entry_blob_size != 12 ||
+ header->function_blob_size != 16 ||
+ header->callback_blob_size != 12 ||
+ header->signal_blob_size != 12 ||
+ header->vfunc_blob_size != 16 ||
+ header->arg_blob_size != 12 ||
+ header->property_blob_size != 12 ||
+ header->field_blob_size != 12 ||
+ header->value_blob_size != 12 ||
+ header->constant_blob_size != 20 ||
+ header->error_domain_blob_size != 16 ||
+ header->annotation_blob_size != 12 ||
+ header->signature_blob_size != 8 ||
+ header->enum_blob_size != 20 ||
+ header->struct_blob_size != 20 ||
+ header->object_blob_size != 32 ||
+ header->interface_blob_size != 28 ||
+ header->union_blob_size != 28)
+ {
+ g_set_error (error,
+ G_METADATA_ERROR,
+ G_METADATA_ERROR_INVALID_HEADER,
+ "Blob size mismatch");
+ return FALSE;
+ }
+
if (!is_aligned (header->directory))
{
g_set_error (error,
@@ -176,16 +229,17 @@
gboolean return_type,
GError **error)
{
- ArrayTypeBlob *blob = (ArrayTypeBlob*)&metadata->data[offset];
- TypeHeader *header = (TypeHeader *)&metadata->data[offset];
+ ArrayTypeBlob *blob;
- if (!header->pointer)
+ blob = (ArrayTypeBlob*)&metadata->data[offset];
+
+ if (!blob->pointer)
{
g_set_error (error,
G_METADATA_ERROR,
G_METADATA_ERROR_INVALID_BLOB,
- "Pointer type exected for tag %d", header->tag);
- return FALSE;
+ "Pointer type exected for tag %d", blob->tag);
+ return FALSE;
}
/* FIXME validate length */
@@ -199,6 +253,32 @@
}
static gboolean
+validate_iface_type_blob (GMetadata *metadata,
+ guint32 offset,
+ guint32 signature_offset,
+ gboolean return_type,
+ GError **error)
+{
+ InterfaceTypeBlob *blob;
+ Header *header;
+
+ header = (Header *)metadata->data;
+
+ blob = (InterfaceTypeBlob*)&metadata->data[offset];
+
+ if (blob->interface == 0 || blob->interface > header->n_entries)
+ {
+ g_set_error (error,
+ G_METADATA_ERROR,
+ G_METADATA_ERROR_INVALID_BLOB,
+ "Invalid directory index %d", blob->interface);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static gboolean
validate_param_type_blob (GMetadata *metadata,
guint32 offset,
guint32 signature_offset,
@@ -206,17 +286,17 @@
gint n_params,
GError **error)
{
- ParamTypeBlob *blob = (ParamTypeBlob*)&metadata->data[offset];
- TypeHeader *header = (TypeHeader *)&metadata->data[offset];
+ ParamTypeBlob *blob;
gint i;
+ blob = (ParamTypeBlob*)&metadata->data[offset];
- if (!header->pointer)
+ if (!blob->pointer)
{
g_set_error (error,
G_METADATA_ERROR,
G_METADATA_ERROR_INVALID_BLOB,
- "Pointer type exected for tag %d", header->tag);
+ "Pointer type exected for tag %d", blob->tag);
return FALSE;
}
@@ -249,39 +329,35 @@
GError **error)
{
ErrorTypeBlob *blob;
- TypeHeader *type_header;
Header *header;
gint i;
DirEntry *entry;
- guint16 *domain;
blob = (ErrorTypeBlob*)&metadata->data[offset];
- type_header = (TypeHeader*)&metadata->data[offset];
header = (Header *)metadata->data;
- if (!type_header->pointer)
+ if (!blob->pointer)
{
g_set_error (error,
G_METADATA_ERROR,
G_METADATA_ERROR_INVALID_BLOB,
- "Pointer type exected for tag %d", type_header->tag);
- return FALSE;
+ "Pointer type exected for tag %d", blob->tag);
+ return FALSE;
}
- domain = (guint16*)&metadata->data[offset + sizeof(ErrorTypeBlob)];
- for (i = 0; i < blob->n_domains; i++, domain++)
+ for (i = 0; i < blob->n_domains; i++)
{
- if (*domain == 0 || *domain > header->n_entries)
+ if (blob->domains[i] == 0 || blob->domains[i] > header->n_entries)
{
g_set_error (error,
G_METADATA_ERROR,
G_METADATA_ERROR_INVALID_BLOB,
- "Invalid directory index %d", *domain);
+ "Invalid directory index %d", blob->domains[i]);
return FALSE;
}
- entry = g_metadata_get_dir_entry (metadata, *domain);
+ entry = g_metadata_get_dir_entry (metadata, blob->domains[i]);
if (entry->blob_type != BLOB_TYPE_ERROR_DOMAIN &&
(entry->local || entry->blob_type != BLOB_TYPE_INVALID))
@@ -305,14 +381,14 @@
GError **error)
{
SimpleTypeBlob *simple;
- TypeHeader *header;
-
+ InterfaceTypeBlob *iface;
+
simple = (SimpleTypeBlob *)&metadata->data[offset];
- header = (TypeHeader *)&metadata->data[offset];
- if (TYPE_IS_SIMPLE(header->tag))
+ if (simple->reserved == 0 &&
+ simple->reserved2 == 0)
{
- if (header->tag >= TYPE_TAG_ARRAY)
+ if (simple->tag >= TYPE_TAG_ARRAY)
{
g_set_error (error,
G_METADATA_ERROR,
@@ -321,29 +397,31 @@
return FALSE;
}
- if (header->tag >= TYPE_TAG_UTF8 &&
- !header->pointer)
+ if (simple->tag >= TYPE_TAG_UTF8 &&
+ !simple->pointer)
{
g_set_error (error,
G_METADATA_ERROR,
G_METADATA_ERROR_INVALID_BLOB,
- "Pointer type exected for tag %d", header->tag);
- return FALSE;
+ "Pointer type exected for tag %d", simple->tag);
+ return FALSE;
}
return TRUE;
}
- switch (header->tag)
+ iface = (InterfaceTypeBlob*)&metadata->data[simple->offset];
+
+ switch (iface->tag)
{
case TYPE_TAG_ARRAY:
if (!validate_array_type_blob (metadata, simple->offset,
signature_offset, return_type, error))
return FALSE;
break;
- case TYPE_TAG_SYMBOL:
- if (!validate_blob (metadata, simple->offset,
- error))
+ case TYPE_TAG_INTERFACE:
+ if (!validate_iface_type_blob (metadata, simple->offset,
+ signature_offset, return_type, error))
return FALSE;
break;
case TYPE_TAG_LIST:
@@ -608,7 +686,6 @@
0, 0
};
ConstantBlob *blob;
- TypeHeader *header;
SimpleTypeBlob *type;
if (metadata->len < offset + sizeof (ConstantBlob))
@@ -652,12 +729,11 @@
"Misaligned constant value");
return FALSE;
}
-
+
type = (SimpleTypeBlob *)&metadata->data[offset + G_STRUCT_OFFSET (ConstantBlob, type)];
- header = (TypeHeader *)&metadata->data[offset + G_STRUCT_OFFSET (ConstantBlob, type)];
- if (TYPE_IS_SIMPLE(header->tag))
+ if (type->reserved == 0)
{
- if (header->tag == 0)
+ if (type->tag == 0)
{
g_set_error (error,
G_METADATA_ERROR,
@@ -666,8 +742,8 @@
return FALSE;
}
- if (value_size[header->tag] != 0 &&
- blob->size != value_size[header->tag])
+ if (value_size[type->tag] != 0 &&
+ blob->size != value_size[type->tag])
{
g_set_error (error,
G_METADATA_ERROR,
@@ -988,6 +1064,17 @@
return FALSE;
}
}
+ else
+ {
+ if (blob->gtype_name || blob->gtype_init)
+ {
+ g_set_error (error,
+ G_METADATA_ERROR,
+ G_METADATA_ERROR_INVALID_BLOB,
+ "Gtype data in struct");
+ return FALSE;
+ }
+ }
if (metadata->len < offset + sizeof (StructBlob) +
blob->n_fields * sizeof (FieldBlob) +
@@ -1073,6 +1160,17 @@
return FALSE;
}
}
+ else
+ {
+ if (blob->gtype_name || blob->gtype_init)
+ {
+ g_set_error (error,
+ G_METADATA_ERROR,
+ G_METADATA_ERROR_INVALID_BLOB,
+ "Gtype data in unregistered enum");
+ return FALSE;
+ }
+ }
if (!is_name (metadata->data, blob->name))
{
Modified: trunk/girepository/gmetadata.h
==============================================================================
--- trunk/girepository/gmetadata.h (original)
+++ trunk/girepository/gmetadata.h Tue Apr 22 22:48:16 2008
@@ -28,7 +28,6 @@
G_BEGIN_DECLS
#define G_IDL_MAGIC "GOBJ\nMETADATA\r\n\032"
-#define G_IDL_MAGIC_ESCAPED "GOBJ\\nMETADATA\\r\\n\\032"
enum
{
@@ -96,6 +95,10 @@
guint32 offset;
} DirEntry;
+
+#define TYPE_POINTER_MASK 1 << 7
+#define TYPE_TAG_MASK 63
+
typedef enum
{
TYPE_TAG_VOID = 0,
@@ -118,34 +121,28 @@
TYPE_TAG_DOUBLE = 17,
TYPE_TAG_UTF8 = 18,
TYPE_TAG_FILENAME = 19,
- TYPE_TAG_SYMBOL = 20,
- TYPE_TAG_ARRAY = 21,
+ TYPE_TAG_ARRAY = 20,
+ TYPE_TAG_INTERFACE = 21,
TYPE_TAG_LIST = 22,
TYPE_TAG_SLIST = 23,
TYPE_TAG_HASH = 24,
TYPE_TAG_ERROR = 25
} TypeTag;
-typedef struct
+typedef union
{
- guint pointer :1;
- guint reserved :2;
- guint tag :5;
-} TypeHeader;
-
-#define TYPE_IS_SIMPLE(tAG) (tAG < TYPE_TAG_SYMBOL ? TRUE : FALSE)
-
-#define TYPE_IS_SYMBOL(tAG) (tAG == TYPE_TAG_SYMBOL ? TRUE : FALSE)
-
-#define TYPE_IS_COMPLEX(tAG) (tAG > TYPE_TAG_SYMBOL ? TRUE : FALSE)
-
-typedef struct
-{
- TypeHeader header;
-
+ struct
+ {
+ guint reserved : 8;
+ guint reserved2 :16;
+ guint pointer : 1;
+ guint reserved3 : 2;
+ guint tag : 5;
+ };
guint32 offset;
} SimpleTypeBlob;
+
typedef struct
{
guint32 name;
@@ -174,9 +171,7 @@
guint16 n_arguments;
-#if 0
ArgBlob arguments[];
-#endif
} SignatureBlob;
typedef struct
@@ -217,13 +212,25 @@
guint32 signature;
} CallbackBlob;
+typedef struct
+{
+ guint pointer :1;
+ guint reserved :2;
+ guint tag :5;
+ guint8 reserved2;
+ guint16 interface;
+} InterfaceTypeBlob;
+
typedef struct
{
- TypeHeader header;
+ guint pointer :1;
+ guint reserved :2;
+ guint tag :5;
guint zero_terminated :1;
guint has_length :1;
guint reserved2 :6;
+
guint16 length;
SimpleTypeBlob type;
@@ -231,24 +238,26 @@
typedef struct
{
- TypeHeader header;
+ guint pointer :1;
+ guint reserved :2;
+ guint tag :5;
guint8 reserved2;
guint16 n_types;
-#if 0
+
SimpleTypeBlob type[];
-#endif
} ParamTypeBlob;
typedef struct
{
- TypeHeader header;
+ guint pointer :1;
+ guint reserved :2;
+ guint tag :5;
+ guint8 reserved2;
guint16 n_domains;
-#if 0
guint16 domains[];
-#endif
} ErrorTypeBlob;
typedef struct
@@ -362,9 +371,7 @@
guint16 n_values;
guint16 reserved2;
-#if 0
- ValueBlob values[];
-#endif
+ ValueBlob values[];
} EnumBlob;
typedef struct
@@ -439,9 +446,10 @@
guint16 n_vfuncs;
guint16 n_constants;
+ guint16 interfaces[];
+
#if 0
/* variable-length parts of the blob */
- guint16 interfaces[];
FieldBlob fields[];
PropertyBlob properties[];
FunctionBlob methods[];
@@ -468,10 +476,10 @@
guint16 n_vfuncs;
guint16 n_constants;
+ guint16 prerequisites[];
-#if 0
+#if 0
/* variable-length parts of the blob */
- guint16 prerequisites[];
PropertyBlob properties[];
FunctionBlob methods[];
SignalBlob signals[];
@@ -513,8 +521,11 @@
DirEntry *g_metadata_get_dir_entry (GMetadata *metadata,
guint16 index);
+void g_metadata_check_sanity (void);
+
#define g_metadata_get_string(metadata,offset) ((const gchar*)&(metadata->data)[(offset)])
+
typedef enum
{
G_METADATA_ERROR_INVALID,
Modified: trunk/tests/Makefile.am
==============================================================================
--- trunk/tests/Makefile.am (original)
+++ trunk/tests/Makefile.am Tue Apr 22 22:48:16 2008
@@ -1,4 +1,4 @@
-SUBDIRS = invoke parser
+SUBDIRS = . invoke parser
EXTRA_DIST = \
roundtrips.sh \
@@ -17,11 +17,4 @@
xref1.test \
xref2.test
-TESTS_ENVIRONMENT = \
- LIBTOOL="$(LIBTOOL)" \
- GIREPO_CFLAGS="$(GIREPO_CFLAGS)" \
- GIREPO_LIBS="$(GIREPO_LIBS)" \
- CC="$(CC)" \
- GIREPOPATH="."
-
TESTS = roundtrips.sh
Modified: trunk/tests/invoke/Makefile.am
==============================================================================
--- trunk/tests/invoke/Makefile.am (original)
+++ trunk/tests/invoke/Makefile.am Tue Apr 22 22:48:16 2008
@@ -5,24 +5,29 @@
testlibdir = /tmp
install-testlibLTLIBRARIES: # prevent it from being installed
-testfns_la_SOURCES =\
- testfns.c\
+
+testfns_la_SOURCES = \
+ testfns.c \
testfns-metadata.c
testfns_la_CFLAGS = $(GIREPO_CFLAGS) -I$(top_srcdir)/girepository
testfns_la_LDFLAGS = -module -avoid-version
testfns_la_LIBADD = $(GIREPO_LIBS) $(top_builddir)/girepository/libgirepository.la
-BUILT_SOURCES = testfns-metadata.c
-CLEANFILES = testfns-metadata.c
+BUILT_SOURCES = testfns-metadata.c test.repo
+CLEANFILES = testfns-metadata.c test.repo
testfns-metadata.c: testfns.xml $(top_builddir)/tools/g-idl-compiler
$(top_builddir)/tools/g-idl-compiler $(srcdir)/testfns.xml -o testfns-metadata.c
+test.repo: testfns.xml
+ $(top_builddir)/tools/g-idl-compiler --shared-library testfns.la $< --raw -o $@
+
invoke_SOURCES = invoke.c
invoke_CFLAGS = $(GIREPO_CFLAGS) -I$(top_srcdir)/girepository
invoke_LDADD = $(GIREPO_LIBS) $(top_builddir)/girepository/libgirepository.la
-EXTRA_DIST = testfns.xml
-TESTS = invoke
+TESTS = invoke invoke-namespace-find.sh
+
+EXTRA_DIST = invoke-namespace-find.sh testfns.xml
TESTS_ENVIRONMENT = GIREPOPATH="."
Modified: trunk/tests/invoke/invoke.c
==============================================================================
--- trunk/tests/invoke/invoke.c (original)
+++ trunk/tests/invoke/invoke.c Tue Apr 22 22:48:16 2008
@@ -30,11 +30,24 @@
testfns,
g_irepository_get_n_infos (rep, "test"));
- handle = g_module_open (testfns, 0);
- if (!handle)
+ if (argc == 1)
{
- g_error ("module open failed: %s\n", g_module_error ());
- return;
+ handle = g_module_open (testfns, 0);
+ if (!handle)
+ {
+ g_error ("module open failed: %s\n", g_module_error ());
+ return;
+ }
+ }
+ else
+ {
+ name = g_irepository_register_file (rep, "test", &error);
+ if (error)
+ {
+ g_error ("Unable to load metadata 'test': %s", error->message);
+ return;
+ }
+ g_print ("Loaded %s from test.gmeta\n", name);
}
g_print ("after dlopening %s: %d infos in the repository\n",
Modified: trunk/tests/roundtrips.sh
==============================================================================
--- trunk/tests/roundtrips.sh (original)
+++ trunk/tests/roundtrips.sh Tue Apr 22 22:48:16 2008
@@ -1,12 +1,26 @@
-#! /bin/sh -x
-#
-SIMPLE_TESTS="enum.test struct.test constant.test union.test array.test types.test boxed.test errors.test function.test interface.test object.test xref1.test xref2.test"
+#! /bin/sh
+
+SIMPLE_TESTS="array.test boxed.test enum.test errors.test function.test interface.test struct.test union.test"
for i in $SIMPLE_TESTS; do
- ../tools/g-idl-compiler -o $i.c $srcdir/$i
- $LIBTOOL --tag=CC --mode=compile $CC -c $GIREPO_CFLAGS -I$srcdir/../girepository $i.c
- $LIBTOOL --tag=CC --mode=link $CC -module -avoid-version -rpath /tmp -o $i.la $i.lo ../girepository/libgirepository.la $GIREPO_LIBS
- ../tools/g-idl-generate $i.la > $i.res;
- diff -u $srcdir/$i $i.res || exit 1;
- rm -f $i.res $i.la $i.lo $i.o $i.c
+ echo $i
+ ../tools/g-idl-compiler --raw $srcdir/$i > $i.1;
+ ../tools/g-idl-generate --raw $i.1 > $i.2;
+ diff -u $srcdir/$i $i.2 || exit 1;
+ rm $i.1 $i.2
done
+
+../tools/g-idl-compiler --raw --module=Foo $srcdir/object.test $srcdir/gobject.test > object.test.1
+../tools/g-idl-generate --raw object.test.1 > object.test.2
+diff -u $srcdir/object.test object.test.2 || exit 1
+rm object.test.1 object.test.2
+
+../tools/g-idl-compiler --raw --module=Foo $srcdir/xref1.test $srcdir/xref2.test > xref1.test.1
+../tools/g-idl-generate --raw xref1.test.1 > xref1.test.2
+diff -u $srcdir/xref1.test xref1.test.2 || exit 1
+rm xref1.test.1 xref1.test.2
+
+../tools/g-idl-compiler --raw --module=Bar $srcdir/xref1.test $srcdir/xref2.test > xref2.test.1
+../tools/g-idl-generate --raw xref2.test.1 > xref2.test.2
+diff -u $srcdir/xref2.test xref2.test.2 || exit 1
+rm xref2.test.1 xref2.test.2
Modified: trunk/tools/Makefile.am
==============================================================================
--- trunk/tools/Makefile.am (original)
+++ trunk/tools/Makefile.am Tue Apr 22 22:48:16 2008
@@ -4,32 +4,17 @@
-DGIREPO_DEFAULT_SEARCH_PATH="\"$(libdir)\"" \
-I$(top_srcdir)/girepository \
-I$(top_srcdir)/giscanner
-BUILT_SOURCES = gmetadata-header.c
-
-CLEANFILES = gmetadata-header.c
-EXTRA_DIST = quote-file.sh
noinst_LTLIBRARIES = libgirepository-parser.la
bin_PROGRAMS = g-idl-compiler g-idl-generate g-idl-scanner
-gmetadata-header.c: $(top_srcdir)/girepository/gmetadata.h
- $(srcdir)/quote-file.sh $^ $@
-
libgirepository_parser_la_SOURCES = \
gidlmodule.c \
gidlmodule.h \
gidlnode.c \
gidlnode.h \
gidlparser.c \
- gidlparser.h \
- gidlcompilercontext.c \
- gidlcompilercontext.h \
- gidlcompilerentrynode.c \
- gidlcompilerentrynode.h \
- gidlcompilertypenode.c \
- gidlcompilertypenode.h \
- gmetadata-header.c
-
+ gidlparser.h
libgirepository_parser_la_CFLAGS = $(GIREPO_CFLAGS)
g_idl_compiler_SOURCES = compiler.c
Modified: trunk/tools/compiler.c
==============================================================================
--- trunk/tools/compiler.c (original)
+++ trunk/tools/compiler.c Tue Apr 22 22:48:16 2008
@@ -28,9 +28,113 @@
#include "gidlnode.h"
#include "gidlparser.h"
#include "gmetadata.h"
-#include "gidlcompilercontext.h"
-static GLogLevelFlags logged_levels;
+gboolean raw = FALSE;
+gboolean no_init = FALSE;
+gchar **input = NULL;
+gchar *output = NULL;
+gchar *mname = NULL;
+gchar *shlib = NULL;
+gboolean debug = FALSE;
+gboolean verbose = FALSE;
+
+static gchar *
+format_output (GMetadata *metadata)
+{
+ GString *result;
+ gint i;
+
+ result = g_string_sized_new (6 * metadata->len);
+
+ g_string_append_printf (result, "#include <stdlib.h>\n");
+ g_string_append_printf (result, "#include <girepository.h>\n\n");
+
+ g_string_append_printf (result, "const unsigned char _G_METADATA[] = \n{");
+
+ for (i = 0; i < metadata->len; i++)
+ {
+ if (i > 0)
+ g_string_append (result, ", ");
+
+ if (i % 10 == 0)
+ g_string_append (result, "\n\t");
+
+ g_string_append_printf (result, "0x%.2x", metadata->data[i]);
+ }
+
+ g_string_append_printf (result, "\n};\n\n");
+ g_string_append_printf (result, "const gsize _G_METADATA_SIZE = %u;\n\n",
+ (guint)metadata->len);
+
+ if (!no_init)
+ {
+ g_string_append_printf (result,
+ "__attribute__((constructor)) void\n"
+ "register_metadata (void)\n"
+ "{\n"
+ "\tGMetadata *metadata;\n"
+ "\tmetadata = g_metadata_new_from_const_memory (_G_METADATA, _G_METADATA_SIZE);\n"
+ "\tg_irepository_register (NULL, metadata);\n"
+ "}\n\n");
+
+ g_string_append_printf (result,
+ "__attribute__((destructor)) void\n"
+ "unregister_metadata (void)\n"
+ "{\n"
+ "\tg_irepository_unregister (NULL, \"%s\");\n"
+ "}\n",
+ g_metadata_get_namespace (metadata));
+ }
+
+ return g_string_free (result, FALSE);
+}
+
+static void
+write_out_metadata (gchar *prefix,
+ GMetadata *metadata)
+{
+ FILE *file;
+
+ if (output == NULL)
+ file = stdout;
+ else
+ {
+ gchar *filename;
+
+ if (prefix)
+ filename = g_strdup_printf ("%s-%s", prefix, output);
+ else
+ filename = g_strdup (output);
+ file = g_fopen (filename, "w");
+
+ if (file == NULL)
+ {
+ g_fprintf (stderr, "failed to open '%s': %s\n",
+ filename, g_strerror (errno));
+ g_free (filename);
+
+ return;
+ }
+
+ g_free (filename);
+ }
+
+ if (raw)
+ fwrite (metadata->data, 1, metadata->len, file);
+ else
+ {
+ gchar *code;
+
+ code = format_output (metadata);
+ fputs (code, file);
+ g_free (code);
+ }
+
+ if (output != NULL)
+ fclose (file);
+}
+
+GLogLevelFlags logged_levels;
static void log_handler (const gchar *log_domain,
GLogLevelFlags log_level,
@@ -42,43 +146,28 @@
g_log_default_handler (log_domain, log_level, message, user_data);
}
+static GOptionEntry options[] =
+{
+ { "raw", 0, 0, G_OPTION_ARG_NONE, &raw, "emit raw metadata", NULL },
+ { "code", 0, G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &raw, "emit C code", NULL },
+ { "no-init", 0, 0, G_OPTION_ARG_NONE, &no_init, "do not create _init() function", NULL },
+ { "output", 'o', 0, G_OPTION_ARG_FILENAME, &output, "output file", "FILE" },
+ { "module", 'm', 0, G_OPTION_ARG_STRING, &mname, "module to compile", "NAME" },
+ { "shared-library", 'l', 0, G_OPTION_ARG_FILENAME, &shlib, "shared library", "FILE" },
+ { "debug", 0, 0, G_OPTION_ARG_NONE, &debug, "show debug messages", NULL },
+ { "verbose", 0, 0, G_OPTION_ARG_NONE, &verbose, "show verbose messages", NULL },
+ { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &input, NULL, NULL },
+ { NULL, }
+};
+
int
main (int argc, char ** argv)
{
- gboolean no_init = FALSE;
- gchar **input = NULL;
- gchar *output = NULL;
- gchar *mname = NULL;
- gchar *shlib = NULL;
- gboolean debug = FALSE;
- gboolean verbose = FALSE;
-
GOptionContext *context;
GError *error = NULL;
- GList *m, *modules;
+ GList *c, *m, *modules;
gint i;
- GList *c;
- gint entry_id;
- FILE *file;
- GIdlCompilerContext *ctx;
- GOptionEntry options[] =
- {
- { "no-init", 0, 0, G_OPTION_ARG_NONE, &no_init,
- "do not create _init() function", NULL },
- { "output", 'o', 0, G_OPTION_ARG_FILENAME, &output,
- "output file", "FILE" },
- { "module", 'm', 0, G_OPTION_ARG_STRING, &mname,
- "module to compile", "NAME" },
- { "shared-library", 'l', 0, G_OPTION_ARG_FILENAME, &shlib,
- "shared library", "FILE" },
- { "debug", 0, 0, G_OPTION_ARG_NONE, &debug,
- "show debug messages", NULL },
- { "verbose", 0, 0, G_OPTION_ARG_NONE, &verbose,
- "show verbose messages", NULL },
- { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &input,
- NULL, NULL },
- { NULL, }
- };
+ g_metadata_check_sanity ();
context = g_option_context_new ("");
g_option_context_add_main_entries (context, options, NULL);
@@ -96,6 +185,7 @@
if (!input)
{
g_fprintf (stderr, "no input files\n");
+
return 1;
}
@@ -120,8 +210,7 @@
{
GIdlModule *module = m->data;
gchar *prefix;
- GError *err = NULL;
-
+ GMetadata *metadata;
if (mname && strcmp (mname, module->name) != 0)
continue;
@@ -131,71 +220,25 @@
g_free (module->shared_library);
module->shared_library = g_strdup (shlib);
}
-
- if (!mname && (m->next || m->prev) && output)
- prefix = module->name;
- else
- prefix = NULL;
-
- ctx = g_idl_compiler_context_new (module->name, &err);
- if (err != NULL)
+ metadata = g_idl_module_build_metadata (module, modules);
+ if (metadata == NULL)
{
- g_fprintf (stderr, "Error creating new compiler context: %s",
- err->message);
+ g_error ("Failed to build metadata for module '%s'\n", module->name);
- return 1;
+ continue;
}
+ if (!g_metadata_validate (metadata, &error))
+ g_error ("Invalid metadata for module '%s': %s",
+ module->name, error->message);
- /* This is making sure all the types
- * that have local directory entries are already
- * in the entries database.
- *
- * A method of finding out if an external reference is
- * needed
- */
- for (c = module->entries; c; c = c->next)
- {
- GIdlNode *node = (GIdlNode*) c->data;
-
- g_idl_compiler_add_entry (ctx, node);
- }
-
- for (c = module->entries; c; c = c->next)
- {
- GIdlNode *node = (GIdlNode*) c->data;
-
- entry_id = g_idl_compiler_get_entry_id (ctx, node->name);
-
- g_idl_compiler_write_node (node, entry_id, ctx);
- }
-
- if (output == NULL)
- file = stdout;
+ if (!mname && (m->next || m->prev) && output)
+ prefix = module->name;
else
- {
- gchar *filename;
-
- if (prefix)
- filename = g_strdup_printf ("%s-%s", prefix, output);
- else
- filename = g_strdup (output);
- file = g_fopen (filename, "w");
-
- if (file == NULL)
- {
- g_fprintf (stderr, "failed to open '%s': %s\n",
- filename, g_strerror (errno));
- g_free (filename);
-
- return;
- }
-
- g_free (filename);
- }
-
- g_idl_compiler_context_finalize (ctx, file, module->shared_library, &err);
+ prefix = NULL;
- g_idl_compiler_context_destroy (ctx);
+ write_out_metadata (prefix, metadata);
+ g_metadata_free (metadata);
+ metadata = NULL;
/* when writing to stdout, stop after the first module */
if (m->next && !output && !mname)
Modified: trunk/tools/generate.c
==============================================================================
--- trunk/tools/generate.c (original)
+++ trunk/tools/generate.c Tue Apr 22 22:48:16 2008
@@ -38,8 +38,7 @@
GIBaseInfo *info,
FILE *file)
{
- if (g_base_info_get_namespace (info) != 0 &&
- strcmp (namespace, g_base_info_get_namespace (info)) != 0)
+ if (strcmp (namespace, g_base_info_get_namespace (info)) != 0)
g_fprintf (file, "%s.", g_base_info_get_namespace (info));
g_fprintf (file, "%s", g_base_info_get_name (info));
@@ -79,11 +78,11 @@
tag = g_type_info_get_tag (info);
- if (tag < TYPE_TAG_UTF8)
+ if (tag < 18)
g_fprintf (file, "%s%s", basic[tag], g_type_info_is_pointer (info) ? "*" : "");
- else if (tag <= TYPE_TAG_FILENAME)
+ else if (tag < 20)
g_fprintf (file, "%s", basic[tag]);
- else if (tag == TYPE_TAG_ARRAY)
+ else if (tag == 20)
{
gint length;
@@ -102,7 +101,7 @@
g_fprintf (file, "]");
g_base_info_unref ((GIBaseInfo *)type);
}
- else if (tag == TYPE_TAG_SYMBOL)
+ else if (tag == 21)
{
GIBaseInfo *iface = g_type_info_get_interface (info);
write_type_name (namespace, iface, file);
@@ -110,7 +109,7 @@
g_fprintf (file, "*");
g_base_info_unref (iface);
}
- else if (tag == TYPE_TAG_LIST)
+ else if (tag == 22)
{
type = g_type_info_get_param_type (info, 0);
g_fprintf (file, "GList");
@@ -123,7 +122,7 @@
}
g_fprintf (file, "*");
}
- else if (tag == TYPE_TAG_SLIST)
+ else if (tag == 23)
{
type = g_type_info_get_param_type (info, 0);
g_fprintf (file, "GSList");
@@ -136,7 +135,7 @@
}
g_fprintf (file, "*");
}
- else if (tag == TYPE_TAG_HASH)
+ else if (tag == 24)
{
type = g_type_info_get_param_type (info, 0);
g_fprintf (file, "GHashTable");
@@ -153,7 +152,7 @@
}
g_fprintf (file, "*");
}
- else if (tag == TYPE_TAG_ERROR)
+ else if (tag == 25)
{
gint n;
@@ -532,11 +531,8 @@
case GI_TYPE_TAG_FILENAME:
g_fprintf (file, "%s", value->v_string);
break;
- case GI_TYPE_TAG_SYMBOL:
- g_fprintf (file, "%s", value->v_string);
- break;
default:
- g_warning ("Could not get type tag for constant");
+ g_assert_not_reached ();
}
}
@@ -574,22 +570,16 @@
FILE *file)
{
const gchar *name;
- const gchar *type_name = NULL;
- const gchar *type_init = NULL;
+ const gchar *type_name;
+ const gchar *type_init;
gboolean deprecated;
gint i;
name = g_base_info_get_name ((GIBaseInfo *)info);
deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
- /* Make sure this is a registered enum before filling out the
- * GType information
- */
- if (g_enum_info_is_registered ((GIEnumInfo *)info))
- {
- type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info);
- type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info);
- }
+ type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info);
+ type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info);
if (g_base_info_get_type ((GIBaseInfo *)info) == GI_INFO_TYPE_ENUM)
g_fprintf (file, " <enum ");
@@ -1108,17 +1098,12 @@
GModule **dlhandle,
gsize *len)
{
- gpointer metadata;
+ guchar *metadata;
gsize *metadata_size;
GModule *handle;
- handle = g_module_open (filename, G_MODULE_BIND_LOCAL|G_MODULE_BIND_LAZY);
- if (!handle)
- {
- g_printerr("Could not load module '%s'\n", filename);
- return NULL;
- }
- if (!g_module_symbol (handle, "_G_METADATA", &metadata))
+ handle = g_module_open (filename, G_MODULE_BIND_LOCAL|G_MODULE_BIND_LAZY);
+ if (!g_module_symbol (handle, "_G_METADATA", (gpointer *) &metadata))
{
g_printerr ("Could not load metadata from '%s': %s\n",
filename, g_module_error ());
@@ -1137,7 +1122,7 @@
if (dlhandle)
*dlhandle = handle;
- return *((const guchar **) metadata);
+ return metadata;
}
int
@@ -1160,6 +1145,8 @@
g_type_init ();
+ g_metadata_check_sanity ();
+
context = g_option_context_new ("");
g_option_context_add_main_entries (context, options, NULL);
g_option_context_parse (context, &argc, &argv, &error);
@@ -1174,7 +1161,7 @@
for (i = 0; input[i]; i++)
{
GModule *dlhandle = NULL;
- const guchar *metadata = NULL;
+ const guchar *metadata;
gsize len;
if (raw)
Modified: trunk/tools/gidlmodule.c
==============================================================================
--- trunk/tools/gidlmodule.c (original)
+++ trunk/tools/gidlmodule.c Tue Apr 22 22:48:16 2008
@@ -1,7 +1,6 @@
/* GObject introspection: Metadata creation
*
* Copyright (C) 2005 Matthias Clasen
- * Copyright (C) 2008 Codethink Ltd
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -25,11 +24,15 @@
#include "gidlmodule.h"
#include "gidlnode.h"
+#define ALIGN_VALUE(this, boundary) \
+ (( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1)))
+
+
GIdlModule *
g_idl_module_new (const gchar *name, const gchar *shared_library)
{
GIdlModule *module;
-
+
module = g_new (GIdlModule, 1);
module->name = g_strdup (name);
@@ -56,3 +59,157 @@
g_free (module);
}
+
+GMetadata *
+g_idl_module_build_metadata (GIdlModule *module,
+ GList *modules)
+{
+ guchar *metadata;
+ gsize length;
+ gint i;
+ GList *e;
+ Header *header;
+ DirEntry *entry;
+ guint32 header_size;
+ guint32 dir_size;
+ guint32 n_entries;
+ guint32 n_local_entries;
+ guint32 size, offset, offset2, old_offset;
+ GHashTable *strings;
+ GHashTable *types;
+ guchar *data;
+
+ header_size = ALIGN_VALUE (sizeof (Header), 4);
+ n_local_entries = g_list_length (module->entries);
+
+ restart:
+ init_stats ();
+ strings = g_hash_table_new (g_str_hash, g_str_equal);
+ types = g_hash_table_new (g_str_hash, g_str_equal);
+ n_entries = g_list_length (module->entries);
+
+ g_message ("%d entries (%d local)\n", n_entries, n_local_entries);
+
+ dir_size = n_entries * 12;
+ size = header_size + dir_size;
+
+ size += ALIGN_VALUE (strlen (module->name) + 1, 4);
+
+ for (e = module->entries; e; e = e->next)
+ {
+ GIdlNode *node = e->data;
+
+ size += g_idl_node_get_full_size (node);
+ }
+
+ g_message ("allocating %d bytes (%d header, %d directory, %d entries)\n",
+ size, header_size, dir_size, size - header_size - dir_size);
+
+ data = g_malloc0 (size);
+
+ /* fill in header */
+ header = (Header *)data;
+ memcpy (header, G_IDL_MAGIC, 16);
+ header->major_version = 1;
+ header->minor_version = 0;
+ header->reserved = 0;
+ header->n_entries = n_entries;
+ header->n_local_entries = n_local_entries;
+ header->n_annotations = 0;
+ header->annotations = 0; /* filled in later */
+ header->size = 0; /* filled in later */
+ header->namespace = write_string (module->name, strings, data, &header_size);
+ header->shared_library = (module->shared_library?
+ write_string (module->shared_library, strings, data, &header_size)
+ : 0);
+ header->directory = ALIGN_VALUE (header_size, 4);
+ header->entry_blob_size = 12;
+ header->function_blob_size = 16;
+ header->callback_blob_size = 12;
+ header->signal_blob_size = 12;
+ header->vfunc_blob_size = 16;
+ header->arg_blob_size = 12;
+ header->property_blob_size = 12;
+ header->field_blob_size = 12;
+ header->value_blob_size = 12;
+ header->constant_blob_size = 20;
+ header->error_domain_blob_size = 16;
+ header->annotation_blob_size = 12;
+ header->signature_blob_size = 8;
+ header->enum_blob_size = 20;
+ header->struct_blob_size = 20;
+ header->object_blob_size = 32;
+ header->interface_blob_size = 28;
+ header->union_blob_size = 28;
+
+ /* fill in directory and content */
+ entry = (DirEntry *)&data[header->directory];
+
+ offset2 = header->directory + dir_size;
+
+ for (e = module->entries, i = 0; e; e = e->next, i++)
+ {
+ GIdlNode *node = e->data;
+
+ if (strchr (node->name, '.'))
+ {
+ g_error ("Names may not contain '.'");
+ }
+
+ /* we picked up implicit xref nodes, start over */
+ if (i == n_entries)
+ {
+ g_message ("Found implicit cross references, starting over");
+
+ g_hash_table_destroy (strings);
+ g_hash_table_destroy (types);
+ strings = NULL;
+
+ g_free (data);
+ data = NULL;
+
+ goto restart;
+ }
+
+ offset = offset2;
+
+ if (node->type == G_IDL_NODE_XREF)
+ {
+ entry->blob_type = 0;
+ entry->local = FALSE;
+ entry->offset = write_string (((GIdlNodeXRef*)node)->namespace, strings, data, &offset2);
+ entry->name = write_string (node->name, strings, data, &offset2);
+ }
+ else
+ {
+ old_offset = offset;
+ offset2 = offset + g_idl_node_get_size (node);
+
+ entry->blob_type = node->type;
+ entry->local = TRUE;
+ entry->offset = offset;
+ entry->name = write_string (node->name, strings, data, &offset2);
+
+ g_idl_node_build_metadata (node, module, modules,
+ strings, types, data, &offset, &offset2);
+
+ if (offset2 > old_offset + g_idl_node_get_full_size (node))
+ g_error ("left a hole of %d bytes\n", offset2 - old_offset - g_idl_node_get_full_size (node));
+ }
+
+ entry++;
+ }
+
+ dump_stats ();
+ g_hash_table_destroy (strings);
+ g_hash_table_destroy (types);
+
+ header->annotations = offset2;
+
+ g_message ("reallocating to %d bytes", offset2);
+
+ metadata = g_realloc (data, offset2);
+ length = header->size = offset2;
+ return g_metadata_new_from_memory (metadata, length);
+}
+
Modified: trunk/tools/gidlmodule.h
==============================================================================
--- trunk/tools/gidlmodule.h (original)
+++ trunk/tools/gidlmodule.h Tue Apr 22 22:48:16 2008
@@ -40,6 +40,9 @@
const gchar *module_filename);
void g_idl_module_free (GIdlModule *module);
+GMetadata * g_idl_module_build_metadata (GIdlModule *module,
+ GList *modules);
+
G_END_DECLS
#endif /* __G_IDL_MODULE_H__ */
Modified: trunk/tools/gidlnode.c
==============================================================================
--- trunk/tools/gidlnode.c (original)
+++ trunk/tools/gidlnode.c Tue Apr 22 22:48:16 2008
@@ -26,6 +26,36 @@
#include "gidlnode.h"
#include "gmetadata.h"
+static gulong string_count = 0;
+static gulong unique_string_count = 0;
+static gulong string_size = 0;
+static gulong unique_string_size = 0;
+static gulong types_count = 0;
+static gulong unique_types_count = 0;
+
+void
+init_stats (void)
+{
+ string_count = 0;
+ unique_string_count = 0;
+ string_size = 0;
+ unique_string_size = 0;
+ types_count = 0;
+ unique_types_count = 0;
+}
+
+void
+dump_stats (void)
+{
+ g_message ("%lu strings (%lu before sharing), %lu bytes (%lu before sharing)",
+ unique_string_count, string_count, unique_string_size, string_size);
+ g_message ("%lu types (%lu before sharing)", unique_types_count, types_count);
+}
+
+#define ALIGN_VALUE(this, boundary) \
+ (( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1)))
+
+
GIdlNode *
g_idl_node_new (GIdlNodeTypeId type)
{
@@ -320,6 +350,420 @@
g_free (node);
}
+/* returns the fixed size of the blob */
+guint32
+g_idl_node_get_size (GIdlNode *node)
+{
+ GList *l;
+ gint size, n;
+
+ switch (node->type)
+ {
+ case G_IDL_NODE_CALLBACK:
+ size = 12;
+ break;
+
+ case G_IDL_NODE_FUNCTION:
+ size = 16;
+ break;
+
+ case G_IDL_NODE_PARAM:
+ size = 12;
+ break;
+
+ case G_IDL_NODE_TYPE:
+ size = 4;
+ break;
+
+ case G_IDL_NODE_OBJECT:
+ {
+ GIdlNodeInterface *iface = (GIdlNodeInterface *)node;
+
+ n = g_list_length (iface->interfaces);
+ size = 32 + 2 * (n + (n % 2));
+
+ for (l = iface->members; l; l = l->next)
+ size += g_idl_node_get_size ((GIdlNode *)l->data);
+ }
+ break;
+
+ case G_IDL_NODE_INTERFACE:
+ {
+ GIdlNodeInterface *iface = (GIdlNodeInterface *)node;
+
+ n = g_list_length (iface->prerequisites);
+ size = 28 + 2 * (n + (n % 2));
+
+ for (l = iface->members; l; l = l->next)
+ size += g_idl_node_get_size ((GIdlNode *)l->data);
+ }
+ break;
+
+ case G_IDL_NODE_ENUM:
+ case G_IDL_NODE_FLAGS:
+ {
+ GIdlNodeEnum *enum_ = (GIdlNodeEnum *)node;
+
+ size = 20;
+ for (l = enum_->values; l; l = l->next)
+ size += g_idl_node_get_size ((GIdlNode *)l->data);
+ }
+ break;
+
+ case G_IDL_NODE_VALUE:
+ size = 12;
+ break;
+
+ case G_IDL_NODE_STRUCT:
+ {
+ GIdlNodeStruct *struct_ = (GIdlNodeStruct *)node;
+
+ size = 20;
+ for (l = struct_->members; l; l = l->next)
+ size += g_idl_node_get_size ((GIdlNode *)l->data);
+ }
+ break;
+
+ case G_IDL_NODE_BOXED:
+ {
+ GIdlNodeBoxed *boxed = (GIdlNodeBoxed *)node;
+
+ size = 20;
+ for (l = boxed->members; l; l = l->next)
+ size += g_idl_node_get_size ((GIdlNode *)l->data);
+ }
+ break;
+
+ case G_IDL_NODE_PROPERTY:
+ size = 12;
+ break;
+
+ case G_IDL_NODE_SIGNAL:
+ size = 12;
+ break;
+
+ case G_IDL_NODE_VFUNC:
+ size = 16;
+ break;
+
+ case G_IDL_NODE_FIELD:
+ size = 12;
+ break;
+
+ case G_IDL_NODE_CONSTANT:
+ size = 20;
+ break;
+
+ case G_IDL_NODE_ERROR_DOMAIN:
+ size = 16;
+ break;
+
+ case G_IDL_NODE_XREF:
+ size = 0;
+ break;
+
+ case G_IDL_NODE_UNION:
+ {
+ GIdlNodeUnion *union_ = (GIdlNodeUnion *)node;
+
+ size = 28;
+ for (l = union_->members; l; l = l->next)
+ size += g_idl_node_get_size ((GIdlNode *)l->data);
+ for (l = union_->discriminators; l; l = l->next)
+ size += g_idl_node_get_size ((GIdlNode *)l->data);
+ }
+ break;
+
+ default:
+ g_error ("Unhandled node type %d\n", node->type);
+ size = 0;
+ }
+
+ g_debug ("node %p type %d size %d", node, node->type, size);
+
+ return size;
+}
+
+/* returns the full size of the blob including variable-size parts */
+guint32
+g_idl_node_get_full_size (GIdlNode *node)
+{
+ GList *l;
+ gint size, n;
+
+ g_assert (node != NULL);
+
+ switch (node->type)
+ {
+ case G_IDL_NODE_CALLBACK:
+ {
+ GIdlNodeFunction *function = (GIdlNodeFunction *)node;
+ size = 12;
+ size += ALIGN_VALUE (strlen (node->name) + 1, 4);
+ for (l = function->parameters; l; l = l->next)
+ size += g_idl_node_get_full_size ((GIdlNode *)l->data);
+ size += g_idl_node_get_full_size ((GIdlNode *)function->result);
+ }
+ break;
+
+ case G_IDL_NODE_FUNCTION:
+ {
+ GIdlNodeFunction *function = (GIdlNodeFunction *)node;
+ size = 24;
+ size += ALIGN_VALUE (strlen (node->name) + 1, 4);
+ size += ALIGN_VALUE (strlen (function->symbol) + 1, 4);
+ for (l = function->parameters; l; l = l->next)
+ size += g_idl_node_get_full_size ((GIdlNode *)l->data);
+ size += g_idl_node_get_full_size ((GIdlNode *)function->result);
+ }
+ break;
+
+ case G_IDL_NODE_PARAM:
+ {
+ GIdlNodeParam *param = (GIdlNodeParam *)node;
+
+ size = 12;
+ if (node->name)
+ size += ALIGN_VALUE (strlen (node->name) + 1, 4);
+ size += g_idl_node_get_full_size ((GIdlNode *)param->type);
+ }
+ break;
+
+ case G_IDL_NODE_TYPE:
+ {
+ GIdlNodeType *type = (GIdlNodeType *)node;
+ if (type->tag < TYPE_TAG_ARRAY)
+ size = 4;
+ else
+ {
+ switch (type->tag)
+ {
+ case TYPE_TAG_ARRAY:
+ size = 4 + 4;
+ if (type->parameter_type1)
+ size += g_idl_node_get_full_size ((GIdlNode *)type->parameter_type1);
+ break;
+ case TYPE_TAG_INTERFACE:
+ size = 4 + 4;
+ break;
+ case TYPE_TAG_LIST:
+ case TYPE_TAG_SLIST:
+ size = 4 + 4;
+ if (type->parameter_type1)
+ size += g_idl_node_get_full_size ((GIdlNode *)type->parameter_type1);
+ break;
+ case TYPE_TAG_HASH:
+ size = 4 + 4 + 4;
+ if (type->parameter_type1)
+ size += g_idl_node_get_full_size ((GIdlNode *)type->parameter_type1);
+ if (type->parameter_type2)
+ size += g_idl_node_get_full_size ((GIdlNode *)type->parameter_type2);
+ break;
+ case TYPE_TAG_ERROR:
+ {
+ gint n;
+
+ if (type->errors)
+ n = g_strv_length (type->errors);
+ else
+ n = 0;
+
+ size = 4 + 4 + 2 * (n + n % 2);
+ }
+ break;
+ default:
+ g_error ("Unknown type tag %d\n", type->tag);
+ break;
+ }
+ }
+ }
+ break;
+
+ case G_IDL_NODE_OBJECT:
+ {
+ GIdlNodeInterface *iface = (GIdlNodeInterface *)node;
+
+ n = g_list_length (iface->interfaces);
+ size = 32;
+ if (iface->parent)
+ size += ALIGN_VALUE (strlen (iface->parent) + 1, 4);
+ size += ALIGN_VALUE (strlen (node->name) + 1, 4);
+ size += ALIGN_VALUE (strlen (iface->gtype_name) + 1, 4);
+ size += ALIGN_VALUE (strlen (iface->gtype_init) + 1, 4);
+ size += 2 * (n + (n % 2));
+
+ for (l = iface->members; l; l = l->next)
+ size += g_idl_node_get_full_size ((GIdlNode *)l->data);
+ }
+ break;
+
+ case G_IDL_NODE_INTERFACE:
+ {
+ GIdlNodeInterface *iface = (GIdlNodeInterface *)node;
+
+ n = g_list_length (iface->prerequisites);
+ size = 28;
+ size += ALIGN_VALUE (strlen (node->name) + 1, 4);
+ size += ALIGN_VALUE (strlen (iface->gtype_name) + 1, 4);
+ size += ALIGN_VALUE (strlen (iface->gtype_init) + 1, 4);
+ size += 2 * (n + (n % 2));
+
+ for (l = iface->members; l; l = l->next)
+ size += g_idl_node_get_full_size ((GIdlNode *)l->data);
+ }
+ break;
+
+ case G_IDL_NODE_ENUM:
+ case G_IDL_NODE_FLAGS:
+ {
+ GIdlNodeEnum *enum_ = (GIdlNodeEnum *)node;
+
+ size = 20;
+ size += ALIGN_VALUE (strlen (node->name) + 1, 4);
+ if (enum_->gtype_name)
+ {
+ size += ALIGN_VALUE (strlen (enum_->gtype_name) + 1, 4);
+ size += ALIGN_VALUE (strlen (enum_->gtype_init) + 1, 4);
+ }
+
+ for (l = enum_->values; l; l = l->next)
+ size += g_idl_node_get_full_size ((GIdlNode *)l->data);
+ }
+ break;
+
+ case G_IDL_NODE_VALUE:
+ {
+ size = 12;
+ size += ALIGN_VALUE (strlen (node->name) + 1, 4);
+ }
+ break;
+
+ case G_IDL_NODE_STRUCT:
+ {
+ GIdlNodeStruct *struct_ = (GIdlNodeStruct *)node;
+
+ size = 20;
+ size += ALIGN_VALUE (strlen (node->name) + 1, 4);
+ for (l = struct_->members; l; l = l->next)
+ size += g_idl_node_get_full_size ((GIdlNode *)l->data);
+ }
+ break;
+
+ case G_IDL_NODE_BOXED:
+ {
+ GIdlNodeBoxed *boxed = (GIdlNodeBoxed *)node;
+
+ size = 20;
+ size += ALIGN_VALUE (strlen (node->name) + 1, 4);
+ if (boxed->gtype_name)
+ {
+ size += ALIGN_VALUE (strlen (boxed->gtype_name) + 1, 4);
+ size += ALIGN_VALUE (strlen (boxed->gtype_init) + 1, 4);
+ }
+ for (l = boxed->members; l; l = l->next)
+ size += g_idl_node_get_full_size ((GIdlNode *)l->data);
+ }
+ break;
+
+ case G_IDL_NODE_PROPERTY:
+ {
+ GIdlNodeProperty *prop = (GIdlNodeProperty *)node;
+
+ size = 12;
+ size += ALIGN_VALUE (strlen (node->name) + 1, 4);
+ size += g_idl_node_get_full_size ((GIdlNode *)prop->type);
+ }
+ break;
+
+ case G_IDL_NODE_SIGNAL:
+ {
+ GIdlNodeSignal *signal = (GIdlNodeSignal *)node;
+
+ size = 12;
+ size += ALIGN_VALUE (strlen (node->name) + 1, 4);
+ for (l = signal->parameters; l; l = l->next)
+ size += g_idl_node_get_full_size ((GIdlNode *)l->data);
+ size += g_idl_node_get_full_size ((GIdlNode *)signal->result);
+ }
+ break;
+
+ case G_IDL_NODE_VFUNC:
+ {
+ GIdlNodeVFunc *vfunc = (GIdlNodeVFunc *)node;
+
+ size = 16;
+ size += ALIGN_VALUE (strlen (node->name) + 1, 4);
+ for (l = vfunc->parameters; l; l = l->next)
+ size += g_idl_node_get_full_size ((GIdlNode *)l->data);
+ size += g_idl_node_get_full_size ((GIdlNode *)vfunc->result);
+ }
+ break;
+
+ case G_IDL_NODE_FIELD:
+ {
+ GIdlNodeField *field = (GIdlNodeField *)node;
+
+ size = 12;
+ size += ALIGN_VALUE (strlen (node->name) + 1, 4);
+ size += g_idl_node_get_full_size ((GIdlNode *)field->type);
+ }
+ break;
+
+ case G_IDL_NODE_CONSTANT:
+ {
+ GIdlNodeConstant *constant = (GIdlNodeConstant *)node;
+
+ size = 20;
+ size += ALIGN_VALUE (strlen (node->name) + 1, 4);
+ /* FIXME non-string values */
+ size += ALIGN_VALUE (strlen (constant->value) + 1, 4);
+ size += g_idl_node_get_full_size ((GIdlNode *)constant->type);
+ }
+ break;
+
+ case G_IDL_NODE_ERROR_DOMAIN:
+ {
+ GIdlNodeErrorDomain *domain = (GIdlNodeErrorDomain *)node;
+
+ size = 16;
+ size += ALIGN_VALUE (strlen (node->name) + 1, 4);
+ size += ALIGN_VALUE (strlen (domain->getquark) + 1, 4);
+ }
+ break;
+
+ case G_IDL_NODE_XREF:
+ {
+ GIdlNodeXRef *xref = (GIdlNodeXRef *)node;
+
+ size = 0;
+ size += ALIGN_VALUE (strlen (node->name) + 1, 4);
+ size += ALIGN_VALUE (strlen (xref->namespace) + 1, 4);
+ }
+ break;
+
+ case G_IDL_NODE_UNION:
+ {
+ GIdlNodeUnion *union_ = (GIdlNodeUnion *)node;
+
+ size = 28;
+ size += ALIGN_VALUE (strlen (node->name) + 1, 4);
+ for (l = union_->members; l; l = l->next)
+ size += g_idl_node_get_full_size ((GIdlNode *)l->data);
+ for (l = union_->discriminators; l; l = l->next)
+ size += g_idl_node_get_full_size ((GIdlNode *)l->data);
+ }
+ break;
+
+ default:
+ g_error ("Unknown type tag %d\n", node->type);
+ size = 0;
+ }
+
+ g_debug ("node %p type %d full size %d", node, node->type, size);
+
+ return size;
+}
+
int
g_idl_node_cmp (GIdlNode *node,
GIdlNode *other)
@@ -519,3 +963,1116 @@
return idx;
}
+static void
+serialize_type (GIdlModule *module,
+ GList *modules,
+ GIdlNodeType *node,
+ GString *str)
+{
+ gint i;
+ const gchar* basic[] = {
+ "void",
+ "gboolean",
+ "gint8",
+ "guint8",
+ "gint16",
+ "guint16",
+ "gint32",
+ "guint32",
+ "gint64",
+ "guint64",
+ "gint",
+ "guint",
+ "glong",
+ "gulong",
+ "gssize",
+ "gsize",
+ "gfloat",
+ "gdouble",
+ "utf8",
+ "filename"
+ };
+
+ if (node->tag < 20)
+ {
+ g_string_append_printf (str, "%s%s",
+ basic[node->tag], node->is_pointer ? "*" : "");
+ }
+ else if (node->tag == 20)
+ {
+ serialize_type (module, modules, node->parameter_type1, str);
+ g_string_append (str, "[");
+
+ if (node->has_length)
+ g_string_append_printf (str, "length=%d", node->length);
+
+ if (node->zero_terminated)
+ g_string_append_printf (str, "%szero-terminated=1",
+ node->has_length ? "," : "");
+
+ g_string_append (str, "]");
+ }
+ else if (node->tag == 21)
+ {
+ GIdlNode *iface;
+ gchar *name;
+
+ iface = find_entry_node (module, modules, node->interface, NULL);
+ if (iface)
+ name = iface->name;
+ else
+ {
+ g_warning ("Interface for type reference %s not found", node->interface);
+ name = node->interface;
+ }
+
+ g_string_append_printf (str, "%s%s", name, node->is_pointer ? "*" : "");
+ }
+ else if (node->tag == 22)
+ {
+ g_string_append (str, "GList");
+ if (node->parameter_type1)
+ {
+ g_string_append (str, "<");
+ serialize_type (module, modules, node->parameter_type1, str);
+ g_string_append (str, ">");
+ }
+ }
+ else if (node->tag == 23)
+ {
+ g_string_append (str, "GSList");
+ if (node->parameter_type1)
+ {
+ g_string_append (str, "<");
+ serialize_type (module, modules, node->parameter_type1, str);
+ g_string_append (str, ">");
+ }
+ }
+ else if (node->tag == 24)
+ {
+ g_string_append (str, "GHashTable<");
+ if (node->parameter_type1)
+ {
+ g_string_append (str, "<");
+ serialize_type (module, modules, node->parameter_type1, str);
+ g_string_append (str, ",");
+ serialize_type (module, modules, node->parameter_type2, str);
+ g_string_append (str, ">");
+ }
+ }
+ else if (node->tag == 25)
+ {
+ g_string_append (str, "GError");
+ if (node->errors)
+ {
+ g_string_append (str, "<");
+ for (i = 0; node->errors[i]; i++)
+ {
+ if (i > 0)
+ g_string_append (str, ",");
+ g_string_append (str, node->errors[i]);
+ }
+ g_string_append (str, ">");
+ }
+ }
+}
+
+void
+g_idl_node_build_metadata (GIdlNode *node,
+ GIdlModule *module,
+ GList *modules,
+ GHashTable *strings,
+ GHashTable *types,
+ guchar *data,
+ guint32 *offset,
+ guint32 *offset2)
+{
+ GList *l;
+ guint32 old_offset = *offset;
+ guint32 old_offset2 = *offset2;
+
+ switch (node->type)
+ {
+ case G_IDL_NODE_TYPE:
+ {
+ GIdlNodeType *type = (GIdlNodeType *)node;
+ SimpleTypeBlob *blob = (SimpleTypeBlob *)&data[*offset];
+
+ *offset += 4;
+
+ if (type->tag < TYPE_TAG_ARRAY)
+ {
+ blob->reserved = 0;
+ blob->reserved2 = 0;
+ blob->pointer = type->is_pointer;
+ blob->reserved3 = 0;
+ blob->tag = type->tag;
+ }
+ else
+ {
+ GString *str;
+ gchar *s;
+ gpointer value;
+
+ str = g_string_new (0);
+ serialize_type (module, modules, type, str);
+ s = g_string_free (str, FALSE);
+
+ types_count += 1;
+ value = g_hash_table_lookup (types, s);
+ if (value)
+ {
+ blob->offset = GPOINTER_TO_INT (value);
+ g_free (s);
+ }
+ else
+ {
+ unique_types_count += 1;
+ g_hash_table_insert (types, s, GINT_TO_POINTER(*offset2));
+
+ blob->offset = *offset2;
+ switch (type->tag)
+ {
+ case TYPE_TAG_ARRAY:
+ {
+ ArrayTypeBlob *array = (ArrayTypeBlob *)&data[*offset2];
+ guint32 pos;
+
+ array->pointer = 1;
+ array->reserved = 0;
+ array->tag = type->tag;
+ array->zero_terminated = type->zero_terminated;
+ array->has_length = type->has_length;
+ array->reserved2 = 0;
+ array->length = type->length;
+
+ pos = *offset2 + 4;
+ *offset2 += 8;
+
+ g_idl_node_build_metadata ((GIdlNode *)type->parameter_type1,
+ module, modules, strings, types,
+ data, &pos, offset2);
+ }
+ break;
+
+ case TYPE_TAG_INTERFACE:
+ {
+ InterfaceTypeBlob *iface = (InterfaceTypeBlob *)&data[*offset2];
+ *offset2 += 4;
+
+ iface->pointer = type->is_pointer;
+ iface->reserved = 0;
+ iface->tag = type->tag;
+ iface->reserved2 = 0;
+ iface->interface = find_entry (module, modules, type->interface);
+
+ }
+ break;
+
+ case TYPE_TAG_LIST:
+ case TYPE_TAG_SLIST:
+ {
+ ParamTypeBlob *param = (ParamTypeBlob *)&data[*offset2];
+ guint32 pos;
+
+ param->pointer = 1;
+ param->reserved = 0;
+ param->tag = type->tag;
+ param->reserved2 = 0;
+ param->n_types = 1;
+
+ pos = *offset2 + 4;
+ *offset2 += 8;
+
+ g_idl_node_build_metadata ((GIdlNode *)type->parameter_type1,
+ module, modules, strings, types,
+ data, &pos, offset2);
+ }
+ break;
+
+ case TYPE_TAG_HASH:
+ {
+ ParamTypeBlob *param = (ParamTypeBlob *)&data[*offset2];
+ guint32 pos;
+
+ param->pointer = 1;
+ param->reserved = 0;
+ param->tag = type->tag;
+ param->reserved2 = 0;
+ param->n_types = 2;
+
+ pos = *offset2 + 4;
+ *offset2 += 12;
+
+ g_idl_node_build_metadata ((GIdlNode *)type->parameter_type1,
+ module, modules, strings, types,
+ data, &pos, offset2);
+ g_idl_node_build_metadata ((GIdlNode *)type->parameter_type2,
+ module, modules, strings, types,
+ data, &pos, offset2);
+ }
+ break;
+
+ case TYPE_TAG_ERROR:
+ {
+ ErrorTypeBlob *blob = (ErrorTypeBlob *)&data[*offset2];
+ gint i;
+
+ blob->pointer = 1;
+ blob->reserved = 0;
+ blob->tag = type->tag;
+ blob->reserved2 = 0;
+ if (type->errors)
+ blob->n_domains = g_strv_length (type->errors);
+ else
+ blob->n_domains = 0;
+
+ *offset2 = ALIGN_VALUE (*offset2 + 4 + 2 * blob->n_domains, 4);
+ for (i = 0; i < blob->n_domains; i++)
+ blob->domains[i] = find_entry (module, modules, type->errors[i]);
+ }
+ break;
+
+ default:
+ g_error ("Unknown type tag %d\n", type->tag);
+ break;
+ }
+ }
+ }
+ }
+ break;
+
+ case G_IDL_NODE_FIELD:
+ {
+ GIdlNodeField *field = (GIdlNodeField *)node;
+ FieldBlob *blob;
+
+ blob = (FieldBlob *)&data[*offset];
+ *offset += 8;
+
+ blob->name = write_string (node->name, strings, data, offset2);
+ blob->readable = field->readable;
+ blob->writable = field->writable;
+ blob->reserved = 0;
+ blob->bits = 0;
+ blob->struct_offset = field->offset;
+
+ g_idl_node_build_metadata ((GIdlNode *)field->type,
+ module, modules, strings, types,
+ data, offset, offset2);
+ }
+ break;
+
+ case G_IDL_NODE_PROPERTY:
+ {
+ GIdlNodeProperty *prop = (GIdlNodeProperty *)node;
+ PropertyBlob *blob = (PropertyBlob *)&data[*offset];
+ *offset += 8;
+
+ blob->name = write_string (node->name, strings, data, offset2);
+ blob->deprecated = prop->deprecated;
+ blob->readable = prop->readable;
+ blob->writable = prop->writable;
+ blob->construct = prop->construct;
+ blob->construct_only = prop->construct_only;
+ blob->reserved = 0;
+
+ g_idl_node_build_metadata ((GIdlNode *)prop->type,
+ module, modules, strings, types,
+ data, offset, offset2);
+ }
+ break;
+
+ case G_IDL_NODE_FUNCTION:
+ {
+ FunctionBlob *blob = (FunctionBlob *)&data[*offset];
+ SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2];
+ GIdlNodeFunction *function = (GIdlNodeFunction *)node;
+ guint32 signature;
+ gint n;
+
+ signature = *offset2;
+ n = g_list_length (function->parameters);
+
+ *offset += 16;
+ *offset2 += 8 + n * 12;
+
+ blob->blob_type = BLOB_TYPE_FUNCTION;
+ blob->deprecated = function->deprecated;
+ blob->setter = function->is_setter;
+ blob->getter = function->is_getter;
+ blob->constructor = function->is_constructor;
+ blob->wraps_vfunc = function->wraps_vfunc;
+ blob->reserved = 0;
+ blob->index = 0;
+ blob->name = write_string (node->name, strings, data, offset2);
+ blob->symbol = write_string (function->symbol, strings, data, offset2);
+ blob->signature = signature;
+
+ g_idl_node_build_metadata ((GIdlNode *)function->result->type,
+ module, modules, strings, types,
+ data, &signature, offset2);
+
+ blob2->may_return_null = function->result->null_ok;
+ blob2->caller_owns_return_value = function->result->transfer;
+ blob2->caller_owns_return_container = function->result->shallow_transfer;
+ blob2->reserved = 0;
+ blob2->n_arguments = n;
+
+ signature += 4;
+
+ for (l = function->parameters; l; l = l->next)
+ {
+ GIdlNode *param = (GIdlNode *)l->data;
+
+ g_idl_node_build_metadata (param,
+ module, modules, strings, types,
+ data, &signature, offset2);
+ }
+ }
+ break;
+
+ case G_IDL_NODE_CALLBACK:
+ {
+ CallbackBlob *blob = (CallbackBlob *)&data[*offset];
+ SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2];
+ GIdlNodeFunction *function = (GIdlNodeFunction *)node;
+ guint32 signature;
+ gint n;
+
+ signature = *offset2;
+ n = g_list_length (function->parameters);
+
+ *offset += 12;
+ *offset2 += 8 + n * 12;
+
+ blob->blob_type = BLOB_TYPE_CALLBACK;
+ blob->deprecated = function->deprecated;
+ blob->reserved = 0;
+ blob->name = write_string (node->name, strings, data, offset2);
+ blob->signature = signature;
+
+ g_idl_node_build_metadata ((GIdlNode *)function->result->type,
+ module, modules, strings, types,
+ data, &signature, offset2);
+
+ blob2->may_return_null = function->result->null_ok;
+ blob2->caller_owns_return_value = function->result->transfer;
+ blob2->caller_owns_return_container = function->result->shallow_transfer;
+ blob2->reserved = 0;
+ blob2->n_arguments = n;
+
+ signature += 4;
+
+ for (l = function->parameters; l; l = l->next)
+ {
+ GIdlNode *param = (GIdlNode *)l->data;
+
+ g_idl_node_build_metadata (param,
+ module, modules, strings, types,
+ data, &signature, offset2);
+ }
+ }
+ break;
+
+ case G_IDL_NODE_SIGNAL:
+ {
+ SignalBlob *blob = (SignalBlob *)&data[*offset];
+ SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2];
+ GIdlNodeSignal *signal = (GIdlNodeSignal *)node;
+ guint32 signature;
+ gint n;
+
+ signature = *offset2;
+ n = g_list_length (signal->parameters);
+
+ *offset += 12;
+ *offset2 += 8 + n * 12;
+
+ blob->deprecated = signal->deprecated;
+ blob->run_first = signal->run_first;
+ blob->run_last = signal->run_last;
+ blob->run_cleanup = signal->run_cleanup;
+ blob->no_recurse = signal->no_recurse;
+ blob->detailed = signal->detailed;
+ blob->action = signal->action;
+ blob->no_hooks = signal->no_hooks;
+ blob->has_class_closure = 0; /* FIXME */
+ blob->true_stops_emit = 0; /* FIXME */
+ blob->reserved = 0;
+ blob->class_closure = 0; /* FIXME */
+ blob->name = write_string (node->name, strings, data, offset2);
+ blob->signature = signature;
+
+ g_idl_node_build_metadata ((GIdlNode *)signal->result->type,
+ module, modules, strings, types,
+ data, &signature, offset2);
+
+ blob2->may_return_null = signal->result->null_ok;
+ blob2->caller_owns_return_value = signal->result->transfer;
+ blob2->caller_owns_return_container = signal->result->shallow_transfer;
+ blob2->reserved = 0;
+ blob2->n_arguments = n;
+
+ signature += 4;
+
+ for (l = signal->parameters; l; l = l->next)
+ {
+ GIdlNode *param = (GIdlNode *)l->data;
+
+ g_idl_node_build_metadata (param, module, modules, strings, types,
+ data, &signature, offset2);
+ }
+ }
+ break;
+
+ case G_IDL_NODE_VFUNC:
+ {
+ VFuncBlob *blob = (VFuncBlob *)&data[*offset];
+ SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2];
+ GIdlNodeVFunc *vfunc = (GIdlNodeVFunc *)node;
+ guint32 signature;
+ gint n;
+
+ signature = *offset2;
+ n = g_list_length (vfunc->parameters);
+
+ *offset += 16;
+ *offset2 += 8 + n * 12;
+
+ blob->name = write_string (node->name, strings, data, offset2);
+ blob->must_chain_up = 0; /* FIXME */
+ blob->must_be_implemented = 0; /* FIXME */
+ blob->must_not_be_implemented = 0; /* FIXME */
+ blob->class_closure = 0; /* FIXME */
+ blob->reserved = 0;
+
+ blob->struct_offset = vfunc->offset;
+ blob->reserved2 = 0;
+ blob->signature = signature;
+
+ g_idl_node_build_metadata ((GIdlNode *)vfunc->result->type,
+ module, modules, strings, types,
+ data, &signature, offset2);
+
+ blob2->may_return_null = vfunc->result->null_ok;
+ blob2->caller_owns_return_value = vfunc->result->transfer;
+ blob2->caller_owns_return_container = vfunc->result->shallow_transfer;
+ blob2->reserved = 0;
+ blob2->n_arguments = n;
+
+ signature += 4;
+
+ for (l = vfunc->parameters; l; l = l->next)
+ {
+ GIdlNode *param = (GIdlNode *)l->data;
+
+ g_idl_node_build_metadata (param, module, modules, strings,
+ types, data, &signature, offset2);
+ }
+ }
+ break;
+
+ case G_IDL_NODE_PARAM:
+ {
+ ArgBlob *blob = (ArgBlob *)&data[*offset];
+ GIdlNodeParam *param = (GIdlNodeParam *)node;
+
+ *offset += 8;
+
+ blob->name = write_string (node->name, strings, data, offset2);
+ blob->in = param->in;
+ blob->out = param->out;
+ blob->dipper = param->dipper;
+ blob->null_ok = param->null_ok;
+ blob->optional = param->optional;
+ blob->transfer_ownership = param->transfer;
+ blob->transfer_container_ownership = param->shallow_transfer;
+ blob->return_value = param->retval;
+ blob->reserved = 0;
+
+ g_idl_node_build_metadata ((GIdlNode *)param->type, module, modules,
+ strings, types, data, offset, offset2);
+ }
+ break;
+
+ case G_IDL_NODE_STRUCT:
+ {
+ StructBlob *blob = (StructBlob *)&data[*offset];
+ GIdlNodeStruct *struct_ = (GIdlNodeStruct *)node;
+
+ blob->blob_type = BLOB_TYPE_STRUCT;
+ blob->deprecated = struct_->deprecated;
+ blob->unregistered = TRUE;
+ blob->reserved = 0;
+ blob->name = write_string (node->name, strings, data, offset2);
+ blob->gtype_name = 0;
+ blob->gtype_init = 0;
+
+ blob->n_fields = 0;
+ blob->n_methods = 0;
+
+ *offset += 20;
+ for (l = struct_->members; l; l = l->next)
+ {
+ GIdlNode *member = (GIdlNode *)l->data;
+
+ if (member->type == G_IDL_NODE_FIELD)
+ {
+ blob->n_fields++;
+ g_idl_node_build_metadata (member, module, modules, strings,
+ types, data, offset, offset2);
+ }
+ }
+
+ for (l = struct_->members; l; l = l->next)
+ {
+ GIdlNode *member = (GIdlNode *)l->data;
+
+ if (member->type == G_IDL_NODE_FUNCTION)
+ {
+ blob->n_methods++;
+ g_idl_node_build_metadata (member, module, modules, strings,
+ types, data, offset, offset2);
+ }
+ }
+ }
+ break;
+
+ case G_IDL_NODE_BOXED:
+ {
+ StructBlob *blob = (StructBlob *)&data[*offset];
+ GIdlNodeBoxed *boxed = (GIdlNodeBoxed *)node;
+
+ blob->blob_type = BLOB_TYPE_BOXED;
+ blob->deprecated = boxed->deprecated;
+ blob->unregistered = FALSE;
+ blob->reserved = 0;
+ blob->name = write_string (node->name, strings, data, offset2);
+ blob->gtype_name = write_string (boxed->gtype_name, strings, data, offset2);
+ blob->gtype_init = write_string (boxed->gtype_init, strings, data, offset2);
+
+ blob->n_fields = 0;
+ blob->n_methods = 0;
+
+ *offset += 20;
+ for (l = boxed->members; l; l = l->next)
+ {
+ GIdlNode *member = (GIdlNode *)l->data;
+
+ if (member->type == G_IDL_NODE_FIELD)
+ {
+ blob->n_fields++;
+ g_idl_node_build_metadata (member, module, modules, strings,
+ types, data, offset, offset2);
+ }
+ }
+
+ for (l = boxed->members; l; l = l->next)
+ {
+ GIdlNode *member = (GIdlNode *)l->data;
+
+ if (member->type == G_IDL_NODE_FUNCTION)
+ {
+ blob->n_methods++;
+ g_idl_node_build_metadata (member, module, modules, strings,
+ types, data, offset, offset2);
+ }
+ }
+ }
+ break;
+
+ case G_IDL_NODE_UNION:
+ {
+ UnionBlob *blob = (UnionBlob *)&data[*offset];
+ GIdlNodeUnion *union_ = (GIdlNodeUnion *)node;
+
+ blob->blob_type = BLOB_TYPE_UNION;
+ blob->deprecated = union_->deprecated;
+ blob->reserved = 0;
+ blob->name = write_string (node->name, strings, data, offset2);
+ if (union_->gtype_name)
+ {
+ blob->unregistered = FALSE;
+ blob->gtype_name = write_string (union_->gtype_name, strings, data, offset2);
+ blob->gtype_init = write_string (union_->gtype_init, strings, data, offset2);
+ }
+ else
+ {
+ blob->unregistered = TRUE;
+ blob->gtype_name = 0;
+ blob->gtype_init = 0;
+ }
+
+ blob->n_fields = 0;
+ blob->n_functions = 0;
+
+ blob->discriminator_offset = union_->discriminator_offset;
+
+ if (union_->discriminator_type)
+ {
+ *offset += 24;
+ blob->discriminated = TRUE;
+ g_idl_node_build_metadata ((GIdlNode *)union_->discriminator_type,
+ module, modules, strings, types,
+ data, offset, offset2);
+ }
+ else
+ {
+ *offset += 28;
+ blob->discriminated = FALSE;
+ blob->discriminator_type.offset = 0;
+ }
+
+
+ for (l = union_->members; l; l = l->next)
+ {
+ GIdlNode *member = (GIdlNode *)l->data;
+
+ if (member->type == G_IDL_NODE_FIELD)
+ {
+ blob->n_fields++;
+ g_idl_node_build_metadata (member, module, modules, strings,
+ types, data, offset, offset2);
+ }
+ }
+
+ for (l = union_->members; l; l = l->next)
+ {
+ GIdlNode *member = (GIdlNode *)l->data;
+
+ if (member->type == G_IDL_NODE_FUNCTION)
+ {
+ blob->n_functions++;
+ g_idl_node_build_metadata (member, module, modules, strings,
+ types, data, offset, offset2);
+ }
+ }
+
+ if (union_->discriminator_type)
+ {
+ for (l = union_->discriminators; l; l = l->next)
+ {
+ GIdlNode *member = (GIdlNode *)l->data;
+
+ g_idl_node_build_metadata (member, module, modules, strings,
+ types, data, offset, offset2);
+ }
+ }
+ }
+ break;
+
+ case G_IDL_NODE_ENUM:
+ case G_IDL_NODE_FLAGS:
+ {
+ EnumBlob *blob = (EnumBlob *)&data[*offset];
+ GIdlNodeEnum *enum_ = (GIdlNodeEnum *)node;
+
+ *offset += 20;
+
+ if (node->type == G_IDL_NODE_ENUM)
+ blob->blob_type = BLOB_TYPE_ENUM;
+ else
+ blob->blob_type = BLOB_TYPE_FLAGS;
+
+ blob->deprecated = enum_->deprecated;
+ blob->reserved = 0;
+ blob->name = write_string (node->name, strings, data, offset2);
+ if (enum_->gtype_name)
+ {
+ blob->unregistered = FALSE;
+ blob->gtype_name = write_string (enum_->gtype_name, strings, data, offset2);
+ blob->gtype_init = write_string (enum_->gtype_init, strings, data, offset2);
+ }
+ else
+ {
+ blob->unregistered = TRUE;
+ blob->gtype_name = 0;
+ blob->gtype_init = 0;
+ }
+
+ blob->n_values = 0;
+ blob->reserved2 = 0;
+
+ for (l = enum_->values; l; l = l->next)
+ {
+ GIdlNode *value = (GIdlNode *)l->data;
+
+ blob->n_values++;
+ g_idl_node_build_metadata (value, module, modules, strings, types,
+ data, offset, offset2);
+ }
+ }
+ break;
+
+ case G_IDL_NODE_OBJECT:
+ {
+ ObjectBlob *blob = (ObjectBlob *)&data[*offset];
+ GIdlNodeInterface *object = (GIdlNodeInterface *)node;
+
+ blob->blob_type = BLOB_TYPE_OBJECT;
+ blob->deprecated = object->deprecated;
+ blob->reserved = 0;
+ blob->name = write_string (node->name, strings, data, offset2);
+ blob->gtype_name = write_string (object->gtype_name, strings, data, offset2);
+ blob->gtype_init = write_string (object->gtype_init, strings, data, offset2);
+ if (object->parent)
+ blob->parent = find_entry (module, modules, object->parent);
+ else
+ blob->parent = 0;
+
+ blob->n_interfaces = 0;
+ blob->n_fields = 0;
+ blob->n_properties = 0;
+ blob->n_methods = 0;
+ blob->n_signals = 0;
+ blob->n_vfuncs = 0;
+ blob->n_constants = 0;
+
+ *offset += 32;
+ for (l = object->interfaces; l; l = l->next)
+ {
+ blob->n_interfaces++;
+ *(guint16*)&data[*offset] = find_entry (module, modules, (gchar *)l->data);
+ *offset += 2;
+ }
+
+ *offset = ALIGN_VALUE (*offset, 4);
+ for (l = object->members; l; l = l->next)
+ {
+ GIdlNode *member = (GIdlNode *)l->data;
+
+ if (member->type == G_IDL_NODE_FIELD)
+ {
+ blob->n_fields++;
+ g_idl_node_build_metadata (member, module, modules, strings,
+ types, data, offset, offset2);
+ }
+ }
+
+ *offset = ALIGN_VALUE (*offset, 4);
+ for (l = object->members; l; l = l->next)
+ {
+ GIdlNode *member = (GIdlNode *)l->data;
+
+ if (member->type == G_IDL_NODE_PROPERTY)
+ {
+ blob->n_properties++;
+ g_idl_node_build_metadata (member, module, modules, strings,
+ types, data, offset, offset2);
+ }
+ }
+
+ *offset = ALIGN_VALUE (*offset, 4);
+ for (l = object->members; l; l = l->next)
+ {
+ GIdlNode *member = (GIdlNode *)l->data;
+
+ if (member->type == G_IDL_NODE_FUNCTION)
+ {
+ blob->n_methods++;
+ g_idl_node_build_metadata (member, module, modules, strings,
+ types, data, offset, offset2);
+ }
+ }
+
+ *offset = ALIGN_VALUE (*offset, 4);
+ for (l = object->members; l; l = l->next)
+ {
+ GIdlNode *member = (GIdlNode *)l->data;
+
+ if (member->type == G_IDL_NODE_SIGNAL)
+ {
+ blob->n_signals++;
+ g_idl_node_build_metadata (member, module, modules, strings,
+ types, data, offset, offset2);
+ }
+ }
+
+ *offset = ALIGN_VALUE (*offset, 4);
+ for (l = object->members; l; l = l->next)
+ {
+ GIdlNode *member = (GIdlNode *)l->data;
+
+ if (member->type == G_IDL_NODE_VFUNC)
+ {
+ blob->n_vfuncs++;
+ g_idl_node_build_metadata (member, module, modules, strings,
+ types, data, offset, offset2);
+ }
+ }
+
+ *offset = ALIGN_VALUE (*offset, 4);
+ for (l = object->members; l; l = l->next)
+ {
+ GIdlNode *member = (GIdlNode *)l->data;
+
+ if (member->type == G_IDL_NODE_CONSTANT)
+ {
+ blob->n_constants++;
+ g_idl_node_build_metadata (member, module, modules, strings,
+ types, data, offset, offset2);
+ }
+ }
+ }
+ break;
+
+ case G_IDL_NODE_INTERFACE:
+ {
+ InterfaceBlob *blob = (InterfaceBlob *)&data[*offset];
+ GIdlNodeInterface *iface = (GIdlNodeInterface *)node;
+
+ blob->blob_type = BLOB_TYPE_INTERFACE;
+ blob->deprecated = iface->deprecated;
+ blob->reserved = 0;
+ blob->name = write_string (node->name, strings, data, offset2);
+ blob->gtype_name = write_string (iface->gtype_name, strings, data, offset2);
+ blob->gtype_init = write_string (iface->gtype_init, strings, data, offset2);
+ blob->n_prerequisites = 0;
+ blob->n_properties = 0;
+ blob->n_methods = 0;
+ blob->n_signals = 0;
+ blob->n_vfuncs = 0;
+ blob->n_constants = 0;
+
+ *offset += 28;
+ for (l = iface->prerequisites; l; l = l->next)
+ {
+ blob->n_prerequisites++;
+ *(guint16*)&data[*offset] = find_entry (module, modules, (gchar *)l->data);
+ *offset += 2;
+ }
+
+ *offset = ALIGN_VALUE (*offset, 4);
+ for (l = iface->members; l; l = l->next)
+ {
+ GIdlNode *member = (GIdlNode *)l->data;
+
+ if (member->type == G_IDL_NODE_PROPERTY)
+ {
+ blob->n_properties++;
+ g_idl_node_build_metadata (member, module, modules, strings,
+ types, data, offset, offset2);
+ }
+ }
+
+ *offset = ALIGN_VALUE (*offset, 4);
+ for (l = iface->members; l; l = l->next)
+ {
+ GIdlNode *member = (GIdlNode *)l->data;
+
+ if (member->type == G_IDL_NODE_FUNCTION)
+ {
+ blob->n_methods++;
+ g_idl_node_build_metadata (member, module, modules, strings,
+ types, data, offset, offset2);
+ }
+ }
+
+ *offset = ALIGN_VALUE (*offset, 4);
+ for (l = iface->members; l; l = l->next)
+ {
+ GIdlNode *member = (GIdlNode *)l->data;
+
+ if (member->type == G_IDL_NODE_SIGNAL)
+ {
+ blob->n_signals++;
+ g_idl_node_build_metadata (member, module, modules, strings,
+ types, data, offset, offset2);
+ }
+ }
+
+ *offset = ALIGN_VALUE (*offset, 4);
+ for (l = iface->members; l; l = l->next)
+ {
+ GIdlNode *member = (GIdlNode *)l->data;
+
+ if (member->type == G_IDL_NODE_VFUNC)
+ {
+ blob->n_vfuncs++;
+ g_idl_node_build_metadata (member, module, modules, strings,
+ types, data, offset, offset2);
+ }
+ }
+
+ *offset = ALIGN_VALUE (*offset, 4);
+ for (l = iface->members; l; l = l->next)
+ {
+ GIdlNode *member = (GIdlNode *)l->data;
+
+ if (member->type == G_IDL_NODE_CONSTANT)
+ {
+ blob->n_constants++;
+ g_idl_node_build_metadata (member, module, modules, strings,
+ types, data, offset, offset2);
+ }
+ }
+ }
+ break;
+
+
+ case G_IDL_NODE_VALUE:
+ {
+ GIdlNodeValue *value = (GIdlNodeValue *)node;
+ ValueBlob *blob = (ValueBlob *)&data[*offset];
+ *offset += 12;
+
+ blob->deprecated = value->deprecated;
+ blob->reserved = 0;
+ blob->name = write_string (node->name, strings, data, offset2);
+ blob->value = value->value;
+ }
+ break;
+
+ case G_IDL_NODE_ERROR_DOMAIN:
+ {
+ GIdlNodeErrorDomain *domain = (GIdlNodeErrorDomain *)node;
+ ErrorDomainBlob *blob = (ErrorDomainBlob *)&data[*offset];
+ *offset += 16;
+
+ blob->blob_type = BLOB_TYPE_ERROR_DOMAIN;
+ blob->deprecated = domain->deprecated;
+ blob->reserved = 0;
+ blob->name = write_string (node->name, strings, data, offset2);
+ blob->get_quark = write_string (domain->getquark, strings, data, offset2);
+ blob->error_codes = find_entry (module, modules, domain->codes);
+ blob->reserved2 = 0;
+ }
+ break;
+
+ case G_IDL_NODE_CONSTANT:
+ {
+ GIdlNodeConstant *constant = (GIdlNodeConstant *)node;
+ ConstantBlob *blob = (ConstantBlob *)&data[*offset];
+ guint32 pos;
+
+ pos = *offset + 8;
+ *offset += 20;
+
+ blob->blob_type = BLOB_TYPE_CONSTANT;
+ blob->deprecated = constant->deprecated;
+ blob->reserved = 0;
+ blob->name = write_string (node->name, strings, data, offset2);
+
+ blob->offset = *offset2;
+ switch (constant->type->tag)
+ {
+ case TYPE_TAG_BOOLEAN:
+ blob->size = 4;
+ *(gboolean*)&data[blob->offset] = parse_boolean_value (constant->value);
+ break;
+ case TYPE_TAG_INT8:
+ blob->size = 1;
+ *(gint8*)&data[blob->offset] = (gint8) parse_int_value (constant->value);
+ break;
+ case TYPE_TAG_UINT8:
+ blob->size = 1;
+ *(guint8*)&data[blob->offset] = (guint8) parse_uint_value (constant->value);
+ break;
+ case TYPE_TAG_INT16:
+ blob->size = 2;
+ *(gint16*)&data[blob->offset] = (gint16) parse_int_value (constant->value);
+ break;
+ case TYPE_TAG_UINT16:
+ blob->size = 2;
+ *(guint16*)&data[blob->offset] = (guint16) parse_uint_value (constant->value);
+ break;
+ case TYPE_TAG_INT32:
+ blob->size = 4;
+ *(gint32*)&data[blob->offset] = (gint32) parse_int_value (constant->value);
+ break;
+ case TYPE_TAG_UINT32:
+ blob->size = 4;
+ *(guint32*)&data[blob->offset] = (guint32) parse_uint_value (constant->value);
+ break;
+ case TYPE_TAG_INT64:
+ blob->size = 8;
+ *(gint64*)&data[blob->offset] = (gint64) parse_int_value (constant->value);
+ break;
+ case TYPE_TAG_UINT64:
+ blob->size = 8;
+ *(guint64*)&data[blob->offset] = (guint64) parse_uint_value (constant->value);
+ break;
+ case TYPE_TAG_INT:
+ blob->size = sizeof (gint);
+ *(gint*)&data[blob->offset] = (gint) parse_int_value (constant->value);
+ break;
+ case TYPE_TAG_UINT:
+ blob->size = sizeof (guint);
+ *(gint*)&data[blob->offset] = (guint) parse_uint_value (constant->value);
+ break;
+ case TYPE_TAG_SSIZE: /* FIXME */
+ case TYPE_TAG_LONG:
+ blob->size = sizeof (glong);
+ *(glong*)&data[blob->offset] = (glong) parse_int_value (constant->value);
+ break;
+ case TYPE_TAG_SIZE: /* FIXME */
+ case TYPE_TAG_ULONG:
+ blob->size = sizeof (gulong);
+ *(gulong*)&data[blob->offset] = (gulong) parse_uint_value (constant->value);
+ break;
+ case TYPE_TAG_FLOAT:
+ blob->size = sizeof (gfloat);
+ *(gfloat*)&data[blob->offset] = (gfloat) parse_float_value (constant->value);
+ break;
+ case TYPE_TAG_DOUBLE:
+ blob->size = sizeof (gdouble);
+ *(gdouble*)&data[blob->offset] = (gdouble) parse_float_value (constant->value);
+ break;
+ case TYPE_TAG_UTF8:
+ case TYPE_TAG_FILENAME:
+ blob->size = strlen (constant->value) + 1;
+ memcpy (&data[blob->offset], constant->value, blob->size);
+ break;
+ }
+ *offset2 += ALIGN_VALUE (blob->size, 4);
+
+ g_idl_node_build_metadata ((GIdlNode *)constant->type, module, modules,
+ strings, types, data, &pos, offset2);
+ }
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ g_debug ("node %p type %d, offset %d -> %d, offset2 %d -> %d",
+ node, node->type, old_offset, *offset, old_offset2, *offset2);
+
+ if (*offset2 - old_offset2 + *offset - old_offset > g_idl_node_get_full_size (node))
+ g_error ("exceeding space reservation !!");
+}
+
+/* if str is already in the pool, return previous location, otherwise write str
+ * to the metadata at offset, put it in the pool and update offset. If the
+ * metadata is not large enough to hold the string, reallocate it.
+ */
+guint32
+write_string (const gchar *str,
+ GHashTable *strings,
+ guchar *data,
+ guint32 *offset)
+{
+ gpointer value;
+ guint32 start;
+
+ string_count += 1;
+ string_size += strlen (str);
+
+ value = g_hash_table_lookup (strings, str);
+
+ if (value)
+ return GPOINTER_TO_INT (value);
+
+ unique_string_count += 1;
+ unique_string_size += strlen (str);
+
+ g_hash_table_insert (strings, (gpointer)str, GINT_TO_POINTER (*offset));
+
+ start = *offset;
+ *offset = ALIGN_VALUE (start + strlen (str) + 1, 4);
+
+ strcpy ((gchar*)&data[start], str);
+
+ return start;
+}
+
Modified: trunk/tools/gidlnode.h
==============================================================================
--- trunk/tools/gidlnode.h (original)
+++ trunk/tools/gidlnode.h Tue Apr 22 22:48:16 2008
@@ -307,12 +307,25 @@
GIdlNode *g_idl_node_new (GIdlNodeTypeId type);
void g_idl_node_free (GIdlNode *node);
-
+guint32 g_idl_node_get_size (GIdlNode *node);
+guint32 g_idl_node_get_full_size (GIdlNode *node);
+void g_idl_node_build_metadata (GIdlNode *node,
+ GIdlModule *module,
+ GList *modules,
+ GHashTable *strings,
+ GHashTable *types,
+ guchar *data,
+ guint32 *offset,
+ guint32 *offset2);
int g_idl_node_cmp (GIdlNode *node,
GIdlNode *other);
gboolean g_idl_node_can_have_member (GIdlNode *node);
void g_idl_node_add_member (GIdlNode *node,
GIdlNodeFunction *member);
+guint32 write_string (const gchar *str,
+ GHashTable *strings,
+ guchar *data,
+ guint32 *offset);
const gchar * g_idl_node_param_direction_string (GIdlNodeParam * node);
Modified: trunk/tools/gidlparser.c
==============================================================================
--- trunk/tools/gidlparser.c (original)
+++ trunk/tools/gidlparser.c Tue Apr 22 22:48:16 2008
@@ -268,7 +268,7 @@
}
else
{
- type->tag = TYPE_TAG_SYMBOL;
+ type->tag = TYPE_TAG_INTERFACE;
type->is_interface = TRUE;
start = *rest;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]