+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.
+
2008-04-22 Johan Dahlin <jdahlin@async.com.br>
* giscanner/girwriter.py:
{
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;
}
}
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);
}
/**
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 *
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;
}
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;
}
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;
}
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;
}
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);
}
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);
}
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)
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 */
{
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
+ (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
{
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]);
}
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;
}
{
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;
}
return NULL;
-}
+}
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:
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,
/* 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);
#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,
{
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)
{
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,
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 */
}
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,
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;
}
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))
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,
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:
0, 0
};
ConstantBlob *blob;
- TypeHeader *header;
SimpleTypeBlob *type;
if (metadata->len < offset + sizeof (ConstantBlob))
"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,
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,
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) +
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))
{
G_BEGIN_DECLS
#define G_IDL_MAGIC "GOBJ\nMETADATA\r\n\032"
-#define G_IDL_MAGIC_ESCAPED "GOBJ\\nMETADATA\\r\\n\\032"
enum
{
guint32 offset;
} DirEntry;
+
+#define TYPE_POINTER_MASK 1 << 7
+#define TYPE_TAG_MASK 63
+
typedef enum
{
TYPE_TAG_VOID = 0,
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;
guint16 n_arguments;
-#if 0
ArgBlob arguments[];
-#endif
} SignatureBlob;
typedef struct
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;
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
guint16 n_values;
guint16 reserved2;
-#if 0
- ValueBlob values[];
-#endif
+ ValueBlob values[];
} EnumBlob;
typedef struct
guint16 n_vfuncs;
guint16 n_constants;
+ guint16 interfaces[];
+
#if 0
/* variable-length parts of the blob */
- guint16 interfaces[];
FieldBlob fields[];
PropertyBlob properties[];
FunctionBlob methods[];
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[];
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,
-SUBDIRS = invoke parser
+SUBDIRS = . invoke parser
EXTRA_DIST = \
roundtrips.sh \
xref1.test \
xref2.test
-TESTS_ENVIRONMENT = \
- LIBTOOL="$(LIBTOOL)" \
- GIREPO_CFLAGS="$(GIREPO_CFLAGS)" \
- GIREPO_LIBS="$(GIREPO_LIBS)" \
- CC="$(CC)" \
- GIREPOPATH="."
-
TESTS = roundtrips.sh
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="."
--- /dev/null
+#! /bin/sh
+exec ./invoke --namespace-find
+#! /bin/sh
+exec ./invoke --namespace-find
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",
-#! /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
-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
#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,
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);
if (!input)
{
g_fprintf (stderr, "no input files\n");
+
return 1;
}
{
GIdlModule *module = m->data;
gchar *prefix;
- GError *err = NULL;
-
+ GMetadata *metadata;
if (mname && strcmp (mname, module->name) != 0)
continue;
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)
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));
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;
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);
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");
}
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");
}
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");
}
g_fprintf (file, "*");
}
- else if (tag == TYPE_TAG_ERROR)
+ else if (tag == 25)
{
gint n;
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 ();
}
}
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 ");
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 ());
if (dlhandle)
*dlhandle = handle;
- return *((const guchar **) metadata);
+ return metadata;
}
int
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);
for (i = 0; input[i]; i++)
{
GModule *dlhandle = NULL;
- const guchar *metadata = NULL;
+ const guchar *metadata;
gsize len;
if (raw)
+++ /dev/null
-/* GObject introspection: Metadata compiler context
- *
- * Copyright (C) 2008 Codethink Ltd
- * 2008 Johan Dahlin
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#include <glib.h>
-
-#include "gidlcompilercontext.h"
-#include "gidlnode.h"
-#include "gmetadata.h"
-
-/* STATIC FUNCTIONS */
-/* ---------------- */
-
-/* Functions for writing final 'C' file */
-/* ------------------------------------ */
-
-extern char gmetadata_header[];
-
-/* Parameters
- * -Struct name
- * -Number of directory entries
- * -Length of strings area.
- */
-static const char struct_header[] =
- "%s\n"
- "{\n"
- " Header " SECTION (header) ";\n"
- " DirEntry " SECTION (directory) "[%d];\n"
- " char " SECTION (strings) "[%d];\n";
-
-/* Parameters
- * -Namespace name
- * -Struct name
- */
-static const char declarations[] =
- "const unsigned char *_G_METADATA = (unsigned char *) &_METADATA_%s;\n"
- "const gsize _G_METADATA_SIZE = sizeof(%s);\n\n";
-
-/* Parameters
- * -Struct name
- * -Namespace name
- */
-static const char init_header[] =
- "static const %s _METADATA_%s =\n"
- "{\n";
-
-/* Parameters
- * -Namespace name
- */
-static const char file_footer[] =
- "__attribute__((constructor)) void\n"
- "register_metadata (void)\n"
- "{\n"
- " GMetadata *metadata;\n"
- " metadata = g_metadata_new_from_const_memory (_G_METADATA, _G_METADATA_SIZE);\n"
- " g_irepository_register (NULL, metadata);\n"
- "}\n"
- "\n"
- "__attribute__((destructor)) void\n"
- "unregister_metadata (void)\n"
- "{\n"
- " g_irepository_unregister (NULL, \"%s\");\n"
- "}\n";
-
-
-typedef struct
-{
- guint entry_id;
- guint dir_id;
-} SymbolEntry;
-
-typedef struct
-{
- GIdlNode *node;
- guint entry_id;
-} DeferredEntry;
-
-static void
-symbol_entry_free (SymbolEntry *symbol_entry)
-{
- g_slice_free (SymbolEntry, symbol_entry);
-}
-
-static void
-deferred_entry_free (DeferredEntry *deferred_entry)
-{
- g_slice_free (DeferredEntry, deferred_entry);
-}
-
-static void
-include_file (const gchar *fname,
- FILE *output)
-{
- FILE *input;
- char c;
-
- input = fopen (fname, "r");
-
- c = fgetc (input);
- while (c != EOF)
- {
- fputc (c, output);
- c = fgetc (input);
- }
-
- fclose (input);
-}
-
-static void
-write_header (GIdlCompilerContext *ctx,
- const gchar *shlib,
- FILE *stream)
-{
- guint32 n_entries;
- guint32 n_local_entries;
- const gchar *header_prototype =
- " {\n"
- /* Magic */
- " \"%s\",\n"
- /* Major version */
- " %d,\n"
- /* Minor version */
- " %d,\n"
- " 0,\n"
- /* n_entries */
- " %d,\n"
- /* n_local_entries */
- " %d,\n"
- /* directory */
- " G_STRUCT_OFFSET(%s, " SECTION (directory) "),\n"
- /* n_annotations */
- " %d,\n"
- /* annotations */
- " %d,\n"
- /* struct_name */
- " sizeof(%s),\n"
- /* struct_name, pointer to name string */
- " G_STRUCT_OFFSET(%s, " SECTION (strings) ") + %d,\n";
-
- fprintf (stream, header_prototype,
- G_IDL_MAGIC_ESCAPED,
- 1,
- 0,
- ctx->directory_entries,
- ctx->directory_local_entries,
- ctx->struct_name,
- 0,
- 0,
- ctx->struct_name,
- ctx->struct_name,
- g_idl_compiler_write_string (ctx, ctx->namespace_name));
-
-
- /* Header */
- if (shlib)
- fprintf (stream, STRING_POINTER,
- ctx->struct_name,
- g_idl_compiler_write_string (ctx, shlib));
- else
- fprintf (stream, "0");
- fprintf (stream, ",\n");
-
- /* Header sizes */
- fprintf (stream,
- " sizeof(DirEntry),\n"
- " sizeof(FunctionBlob),\n"
- " sizeof(CallbackBlob),\n"
- " sizeof(SignalBlob),\n"
- " sizeof(VFuncBlob),\n"
- " sizeof(ArgBlob),\n"
- " sizeof(PropertyBlob),\n"
- " sizeof(FieldBlob),\n"
- " sizeof(ValueBlob),\n"
- " sizeof(AnnotationBlob),\n"
- " sizeof(ConstantBlob),\n"
- " sizeof(ErrorDomainBlob),\n"
- " sizeof(SignatureBlob),\n"
- " sizeof(EnumBlob),\n"
- " sizeof(StructBlob),\n"
- " sizeof(ObjectBlob),\n"
- " sizeof(InterfaceBlob),\n"
- " sizeof(UnionBlob),\n"
- " {0,0,0,0,0,0,0},\n" " },\n\n");
-}
-
-void
-write_compiled (GIdlCompilerContext *ctx, FILE *compiled,
- const gchar *shlib,
- GError **err)
-{
- const char file_header[] =
- "#include <stdlib.h>\n"
- "#include <glib.h>\n"
- "#include <girepository.h>\n";
-
- /* Before doing anything need to add the namespace string */
- g_idl_compiler_write_string (ctx, ctx->namespace_name);
-
- fprintf (compiled, file_header);
- fprintf (compiled, gmetadata_header);
-
- /* write the shlibs string before we write out the whole string length */
- if (shlib)
- g_idl_compiler_write_string (ctx, shlib);
-
- /* +1 is for the null byte right at the end of the strings section */
- fprintf (compiled, struct_header, ctx->struct_name,
- ctx->directory_entries, ctx->string_offset + 1);
-
- /* Include the struct file */
- include_file (ctx->mdata_struct_fn, compiled);
- fprintf (compiled, "};\n\n");
- fprintf (compiled, init_header, ctx->struct_name, ctx->namespace_name);
-
- write_header (ctx, shlib, compiled);
-
- /* Close all the temporary files */
- fclose (ctx->mdata_init);
- fclose (ctx->mdata_string);
- fclose (ctx->mdata_directory);
-
- /* Place directory here */
- fprintf (compiled, " {\n");
- include_file (ctx->mdata_directory_fn, compiled);
- fprintf (compiled, " },\n\n");
-
- /* Place string data here */
- fprintf (compiled, " {\n");
- include_file (ctx->mdata_string_fn, compiled);
- fprintf (compiled, " },\n\n");
-
- /* Include the initializer file */
- include_file (ctx->mdata_init_fn, compiled);
-
- fprintf (compiled, "};\n\n");
-
- /* Write out the metadata declarations */
- fprintf (compiled, declarations, ctx->namespace_name, ctx->struct_name);
-
- fprintf (compiled, file_footer, ctx->namespace_name);
-
- /* Remove the temporary files */
- g_remove (ctx->mdata_struct_fn);
- g_remove (ctx->mdata_init_fn);
- g_remove (ctx->mdata_string_fn);
- g_remove (ctx->mdata_directory_fn);
-}
-
-/* GLOBAL FUNCTIONS */
-/* ---------------- */
-
-GIdlCompilerContext *
-g_idl_compiler_context_new (const gchar *namespace,
- GError **error)
-{
- gint struct_fd, init_fd, string_fd, directory_fd;
- GIdlCompilerContext *ctx;
- GError *tmp_error = NULL;
-
- ctx = g_slice_new0 (GIdlCompilerContext);
- if (!ctx)
- {
- /* FIXME Put proper error quark here */
- g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_NOENT,
- "Could not create output context");
- goto out;
- }
- ctx->strings = g_hash_table_new (g_str_hash, g_str_equal);
- ctx->namespace_name = g_strdup (namespace);
- ctx->struct_name = g_strdup_printf ("struct mdata_%s", namespace);
-
- ctx->entriesdb = g_hash_table_new_full (g_str_hash, g_str_equal,
- (GDestroyNotify)g_free,
- (GDestroyNotify)symbol_entry_free);
- ctx->typesdb = g_hash_table_new (g_str_hash, g_str_equal);
-
- /* Structure definition file */
- struct_fd = g_file_open_tmp ("gicomp-XXXXXX", &ctx->mdata_struct_fn,
- &tmp_error);
- if (tmp_error)
- goto error4;
-
- /* Structure initialization file */
- init_fd = g_file_open_tmp ("gicomp-XXXXXX", &ctx->mdata_init_fn,
- &tmp_error);
- if (tmp_error)
- goto error3;
-
- /* String file */
- string_fd = g_file_open_tmp ("gicomp-XXXXXX", &ctx->mdata_string_fn,
- &tmp_error);
- if (tmp_error)
- goto error2;
-
- /* Directory file */
- directory_fd = g_file_open_tmp ("gicomp-XXXXXX", &ctx->mdata_directory_fn,
- &tmp_error);
- if (tmp_error)
- goto error1;
-
- ctx->mdata_struct = fdopen (struct_fd, "w");
- ctx->mdata_init = fdopen (init_fd, "w");
- ctx->mdata_string = fdopen (string_fd, "w");
- ctx->mdata_directory = fdopen (directory_fd, "w");
-
- goto out;
-
- error1:
- close (directory_fd);
- g_remove (ctx->mdata_directory_fn);
- error2:
- close (string_fd);
- g_remove (ctx->mdata_string_fn);
- error3:
- close (init_fd);
- g_remove (ctx->mdata_init_fn);
- error4:
- close (struct_fd);
- g_remove (ctx->mdata_struct_fn);
- error:
- g_propagate_error (error, tmp_error);
-
- g_free (ctx);
- ctx = NULL;
- out:
- return ctx;
-}
-
-void
-g_idl_compiler_context_finalize (GIdlCompilerContext *ctx,
- FILE *stream,
- const gchar *shlib,
- GError **error)
-{
- fclose (ctx->mdata_struct);
- write_compiled (ctx, stream, shlib, error);
-}
-
-void
-g_idl_compiler_context_destroy (GIdlCompilerContext *ctx)
-{
- g_free (ctx->mdata_struct_fn);
- g_free (ctx->mdata_init_fn);
- g_free (ctx->mdata_string_fn);
- g_free (ctx->mdata_directory_fn);
-
- g_free (ctx->struct_name);
- g_free (ctx->namespace_name);
-
- g_list_foreach (ctx->dtypelist, (GFunc)deferred_entry_free, NULL);
- g_list_free (ctx->dtypelist);
-
- g_list_foreach (ctx->dconstantlist, (GFunc)deferred_entry_free, NULL);
- g_list_free (ctx->dconstantlist);
-
- g_hash_table_destroy (ctx->entriesdb);
- g_hash_table_destroy (ctx->typesdb);
- g_hash_table_destroy (ctx->strings);
- g_slice_free (GIdlCompilerContext, ctx);
-}
-
-
-/**
- * g_idl_compiler_write_string:
- * @ctx:
- * @str:
- * String specific functions
- *
- * If string is already in the pool, return previous location,
- * otherwise write string to the metadata at offset, put it
- * in the pool and update offset.
- */
-guint32
-g_idl_compiler_write_string (GIdlCompilerContext *ctx,
- const gchar *str)
-{
- gpointer value;
- guint32 orig = ctx->string_offset;
-
- g_return_val_if_fail (str != NULL, 0);
-
- if (g_hash_table_lookup_extended (ctx->strings, str, NULL, &value))
- return GPOINTER_TO_INT (value);
-
- g_hash_table_insert (ctx->strings, (gpointer) str,
- GINT_TO_POINTER (ctx->string_offset));
-
- /* +1 is for the null byte that is added at the end of each string */
- ctx->string_offset += strlen (str) + 1;
-
- fprintf (ctx->mdata_string, " \"%s\\0\"\n", str);
-
- return orig;
-}
-
-static guint16
-g_idl_compiler_write_dir_entry (GIdlCompilerContext *ctx,
- guint16 blob_type,
- const gchar *name,
- gint entry_id)
-{
- const char *entry_prototype =
- " {\n" " %d,\n"
- " %d,\n"
- " 0,\n"
- " " STRING_POINTER ", /* %s */\n"
- " " TYPE_POINTER ",\n"
- " },\n";
- guint orig = ctx->directory_entries;
-
- fprintf (ctx->mdata_directory, entry_prototype,
- blob_type,
- TRUE,
- ctx->struct_name, g_idl_compiler_write_string (ctx, name), name,
- ctx->struct_name, entry_id);
-
- ctx->directory_local_entries += 1;
- ctx->directory_entries += 1;
- return orig;
-}
-
-static guint16
-g_idl_compiler_write_xref_entry (GIdlCompilerContext *ctx,
- guint16 blob_type,
- const gchar *name,
- const gchar *namespace)
-{
- const char *entry_prototype =
- " {\n" " %d,\n"
- " %d,\n"
- " 0,\n"
- " " STRING_POINTER ", /* %s */\n"
- " " STRING_POINTER ", /* %s */\n"
- " },\n";
- guint dir_id_res = ctx->directory_entries;
-
- fprintf (ctx->mdata_directory, entry_prototype,
- blob_type,
- FALSE,
- ctx->struct_name, g_idl_compiler_write_string (ctx, name), name,
- ctx->struct_name, g_idl_compiler_write_string (ctx, namespace), name);
-
- ctx->directory_entries += 1;
- return dir_id_res;
-}
-
-/* This is a unique id for each entry in the
- * metadata that may need to be referenced elsewhere.
- * Essentially anything that has to be given a
- * name in the metadata struct.
- */
-gint32
-g_idl_compiler_get_unique_id (void)
-{
- static gint32 i = 0;
- return ++i;
-}
-
-void
-g_idl_compiler_add_entry (GIdlCompilerContext *ctx, GIdlNode *node)
-{
- guint entry_id;
- guint dir_id;
- SymbolEntry *entry;
-
- entry = g_slice_new0 (SymbolEntry);
- entry_id = g_idl_compiler_get_unique_id ();
- dir_id = g_idl_compiler_write_dir_entry (ctx, node->type,
- node->name, entry_id);
-
- entry->entry_id = entry_id;
- /* The directory array is indexed from 1 upwards. Just to confuse us */
- entry->dir_id = dir_id + 1;
-
- g_hash_table_insert (ctx->entriesdb, g_strdup (node->name), entry);
-}
-
-static guint
-g_idl_compiler_add_xref (GIdlCompilerContext *ctx,
- const gchar *name)
-{
- gint dir_id;
- guint n_names;
- gchar **names;
- gchar *symbol;
- gchar *namespace;
- SymbolEntry *entry;
-
- names = g_strsplit (name, ".", 0);
- n_names = g_strv_length (names);
-
- if (n_names < 2)
- {
- g_warning ("External reference with no namespace");
- symbol = g_strjoinv ("", &names[0]);
- namespace = NULL;
- }
- else
- {
- symbol = g_strjoinv (".", &names[1]);
- namespace = names[0];
- }
-
- fprintf (ctx->mdata_directory,
- " {\n"
- " 0,\n"
- " 0,\n"
- " 0,\n"
- " " STRING_POINTER ", /* %s */\n",
- ctx->struct_name,
- g_idl_compiler_write_string (ctx, symbol), name);
-
- if (namespace)
- fprintf (ctx->mdata_directory, " " STRING_POINTER ", /* %s */\n",
- ctx->struct_name, g_idl_compiler_write_string (ctx, namespace),
- name);
- else
- fprintf (ctx->mdata_directory, " 0,\n");
- fprintf (ctx->mdata_directory, " },\n");
-
- dir_id = ctx->directory_entries;
- ctx->directory_entries += 1;
-
- /* The Directory array is indexed from 1 upwards. Just to confuse us */
- entry = g_slice_new0 (SymbolEntry);
- entry->dir_id = dir_id + 1;
- g_hash_table_insert (ctx->entriesdb, g_strdup (name), entry);
-
- g_free(symbol);
- g_strfreev (names);
- return dir_id + 1;
-}
-
-guint
-g_idl_compiler_get_entry_id (GIdlCompilerContext *ctx,
- const gchar *name)
-{
- SymbolEntry *entry;
-
- entry = g_hash_table_lookup (ctx->entriesdb, name);
- return entry->entry_id;
-}
-
-guint
-g_idl_compiler_get_entry_dirid (GIdlCompilerContext *ctx,
- const gchar *name)
-{
- SymbolEntry *entry;
-
- entry = g_hash_table_lookup (ctx->entriesdb, name);
- if (entry)
- return entry->dir_id;
-
- /* If no entry found assume its an external reference */
- return g_idl_compiler_add_xref (ctx, name);
-}
-
-void
-g_idl_compiler_push_deferred_type_node (GIdlCompilerContext *ctx,
- GIdlNode *node,
- guint entry_id)
-{
- DeferredEntry *entry;
-
- entry = g_slice_new (DeferredEntry);
- entry->node = node;
- entry->entry_id = entry_id;
- ctx->dtypelist = g_list_prepend (ctx->dtypelist, entry);
-}
-
-GIdlNode *
-g_idl_compiler_pop_deferred_type_node (GIdlCompilerContext *ctx,
- guint *entry_id)
-{
- DeferredEntry *entry;
- GIdlNode *node;
-
- if (!ctx->dtypelist)
- return NULL;
-
- entry = (DeferredEntry *) ctx->dtypelist->data;
- ctx->dtypelist = g_list_remove (ctx->dtypelist, (gpointer) entry);
- *entry_id = entry->entry_id;
- node = entry->node;
- deferred_entry_free (entry);
- return node;
-}
-
-void
-g_idl_compiler_push_deferred_signature_node (GIdlCompilerContext * ctx,
- GIdlNode * node, guint entry_id)
-{
- DeferredEntry *entry;
-
- entry = g_slice_new (DeferredEntry);
- entry->node = node;
- entry->entry_id = entry_id;
- ctx->dsignaturelist = g_list_prepend (ctx->dsignaturelist, entry);
-}
-
-GIdlNode*
-g_idl_compiler_pop_deferred_signature_node (GIdlCompilerContext *ctx,
- guint *entry_id)
-{
- DeferredEntry *entry;
- GIdlNode *node;
-
- if (!ctx->dsignaturelist)
- return NULL;
-
- entry = (DeferredEntry *) ctx->dsignaturelist->data;
- ctx->dsignaturelist = g_list_remove (ctx->dsignaturelist, entry);
- *entry_id = entry->entry_id;
- node = entry->node;
- deferred_entry_free (entry);
- return node;
-}
-
-void
-g_idl_compiler_push_deferred_constant (GIdlCompilerContext *ctx,
- GIdlNode *node,
- guint entry_id)
-{
- DeferredEntry *constant;
-
- constant = g_slice_new (DeferredEntry);
- constant->node = node;
- constant->entry_id = entry_id;
- ctx->dconstantlist = g_list_prepend (ctx->dconstantlist, constant);
-}
-
-GIdlNode *
-g_idl_compiler_pop_deferred_constant (GIdlCompilerContext *ctx,
- guint *entry_id)
-{
- DeferredEntry *deferred_entry;
- GIdlNode *node;
-
- if (!ctx->dconstantlist)
- return NULL;
-
- deferred_entry = (DeferredEntry *) ctx->dconstantlist->data;
- ctx->dconstantlist = g_list_remove (ctx->dconstantlist, deferred_entry);
- *entry_id = deferred_entry->entry_id;
- node = deferred_entry->node;
- deferred_entry_free (deferred_entry);
- return node;
-}
+++ /dev/null
-
-#ifndef __G_IDL_COMPILER_CONTEXT_H__
-#define __G_IDL_COMPILER_CONTEXT_H__
-
-#include <stdio.h>
-#include <glib.h>
-
-#include "gidlnode.h"
-
-typedef struct _GIdlCompilerContext GIdlCompilerContext;
-
-struct _GIdlCompilerContext
-{
- gchar *namespace_name;
- gchar *struct_name;
-
- gchar *mdata_struct_fn;
- FILE *mdata_struct;
-
- gchar *mdata_init_fn;
- FILE *mdata_init;
-
- guint32 string_offset;
- gchar *mdata_string_fn;
- FILE *mdata_string;
- GHashTable *strings;
-
- guint32 directory_local_entries;
- guint32 directory_entries;
- gchar *mdata_directory_fn;
- FILE *mdata_directory;
-
- /* The entriesdb contains all the
- * types that have a directory entry.
- *
- * It must be filled in before beginning to write
- * out the data. This is because it is used
- * to decide whether a type is available or
- * needs an external reference
- */
- GHashTable *entriesdb;
-
- /* The typesdb is used to store type names to
- * entry ids, so that multiple similar type blobs are
- * not written out
- */
- GHashTable *typesdb;
-
- /* Type blobs are accessed in the middle of writing another
- * entry. Writing them needs to be deferred until after
- * that entry is finished.
- */
- GList *dtypelist;
-
- /* Signature blobs are accessed in the middle of writing
- * other entries, and so need to be deferred.
- *
- * There is no signature node, so the function / callback
- * nodes are stored instead.
- */
- GList *dsignaturelist;
-
- /* Constants have values that are of a variable size,
- * and have to be written out after the entry has finished,
- * so are stored as a variant in this list until the time comes.
- */
- GList *dconstantlist;
-};
-
-GIdlCompilerContext *g_idl_compiler_context_new (const gchar * namespace,
- GError ** err);
-
-void
-g_idl_compiler_context_finalize (GIdlCompilerContext *ctx,
- FILE *stream,
- const gchar *shlib,
- GError **err);
-
-void g_idl_compiler_context_destroy (GIdlCompilerContext * ctx);
-
-guint32 g_idl_compiler_write_string (GIdlCompilerContext * ctx,
- const gchar * str);
-
-gint32 g_idl_compiler_get_unique_id (void);
-
-void g_idl_compiler_add_entry (GIdlCompilerContext *ctx,
- GIdlNode *node);
-
-guint g_idl_compiler_get_entry_id (GIdlCompilerContext * ctx,
- const gchar * name);
-
-guint g_idl_compiler_get_entry_dirid (GIdlCompilerContext * ctx,
- const gchar * name);
-
-void g_idl_compiler_push_deferred_type_node (GIdlCompilerContext * ctx,
- GIdlNode * node,
- guint entry_id);
-
-GIdlNode *g_idl_compiler_pop_deferred_type_node (GIdlCompilerContext * ctx,
- guint * entry_id);
-
-void g_idl_compiler_push_deferred_signature_node (GIdlCompilerContext * ctx,
- GIdlNode * node,
- guint entry_id);
-
-GIdlNode *g_idl_compiler_pop_deferred_signature_node (GIdlCompilerContext * ctx,
- guint * entry_id);
-
-void g_idl_compiler_push_deferred_constant (GIdlCompilerContext * ctx,
- GIdlNode * node,
- guint entry_id);
-
-GIdlNode * g_idl_compiler_pop_deferred_constant (GIdlCompilerContext * ctx,
- guint * entry_id);
-
-#define SECTION(sEC) "info_" #sEC
-#define ID_TO_ENTRY "entry_%d"
-
-/* Parameters (To the string)
- * Metadata struct name
- * Offset into string buffer - Given by g_idl_compiler_write_string()
- */
-#define STRING_POINTER "G_STRUCT_OFFSET(%s," SECTION(strings) ") + %d"
-
-/* Parameters(To the string)
- * Metatada struct name
- * Type name
- */
-#define TYPE_POINTER "G_STRUCT_OFFSET(%s,"ID_TO_ENTRY")"
-
-#endif /*__G_IDL_COMPILER_CONTEXT_H__*/
+++ /dev/null
-/* GObject introspection: Node compilation
- *
- * 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
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "gmetadata.h"
-
-#include "gidlnode.h"
-#include "gidlmodule.h"
-#include "gidlcompilercontext.h"
-#include "gidlcompilertypenode.h"
-
-/* PARAMETER BLOB COMPILATION */
-/*----------------------------*/
-/* Blobs in this section do not get a directory entry.
- * They are not types in themselves but are just information
- * about types, such as the signals of an object or the fields
- * of a struct.
- */
-
-/*VALUE*/
-/* Used in enums and flags */
-static void
-include_value (GIdlNode * node, GIdlCompilerContext * ctx)
-{
- GIdlNodeValue *value = (GIdlNodeValue *) node;
- const gchar *value_prototype = " {%d, %d, " STRING_POINTER ", %d},\n";
-
- fprintf (ctx->mdata_init, value_prototype,
- value->deprecated,
- 0,
- ctx->struct_name, g_idl_compiler_write_string (ctx, node->name),
- value->value);
-}
-
-/*PARAM*/
-/* Used in signatures */
-static void
-include_param (GIdlNode * node, GIdlCompilerContext * ctx)
-{
- GIdlNodeParam *param = (GIdlNodeParam *) node;
-
- const gchar *param_header =
- " {\n"
- " "STRING_POINTER",\n"
- " %d, %d, %d, %d, %d, %d, %d, %d, 0,\n";
-
- fprintf (ctx->mdata_init, param_header,
- ctx->struct_name, g_idl_compiler_write_string (ctx, node->name),
- param->in,
- param->out,
- param->dipper,
- param->null_ok,
- param->optional,
- param->transfer,
- param->shallow_transfer,
- param->retval);
-
- g_idl_compiler_write_simple_type_blob ((GIdlNode *)param->type, ctx);
-
- fprintf(ctx->mdata_init, " },\n");
-}
-
-/*V FUNC*/
-/* Used in objects and interfaces */
-static void
-include_vfunc (GIdlNode * node, GIdlCompilerContext * ctx)
-{
- guint signature_id;
- GIdlNodeVFunc *vfunc = (GIdlNodeVFunc *) node;
- const char *vfunc_header =
- " {\n"
- " "STRING_POINTER",\n"
- " %d, %d, %d, %d, 0, %d,\n"
- " %d, 0,\n"
- " "TYPE_POINTER",\n"
- " },\n";
-
- signature_id = g_idl_compiler_get_unique_id();
-
- g_idl_compiler_push_deferred_signature_node(ctx, node, signature_id);
-
- fprintf(ctx->mdata_init, vfunc_header,
- ctx->struct_name, g_idl_compiler_write_string (ctx, node->name),
- 0, /*FIXME*/
- 0, /*FIXME*/
- 0, /*FIXME*/
- 0, /*FIXME*/
- 0, /*FIXME*/
- vfunc->offset,
- ctx->struct_name, signature_id);
-}
-
-/*PROPERTY*/
-/* Used in objects and interfaces */
-static void
-include_property (GIdlNode * node, GIdlCompilerContext * ctx)
-{
- GIdlNodeProperty *property = (GIdlNodeProperty *) node;
-
- const gchar *property_header =
- " {\n"
- " "STRING_POINTER", %d, %d, %d, %d, %d, 0,\n";
-
- fprintf (ctx->mdata_init, property_header,
- ctx->struct_name, g_idl_compiler_write_string (ctx, node->name),
- property->deprecated,
- property->readable,
- property->writable,
- property->construct,
- property->construct_only);
-
- /*Insert simple type blob here */
- g_idl_compiler_write_simple_type_blob ((GIdlNode *)property->type, ctx);
-
- fprintf (ctx->mdata_init, " },\n");
-}
-
-/*FIELD*/
-/* Used in struct */
-static void
-include_field (GIdlNode * node, GIdlCompilerContext * ctx)
-{
- GIdlNodeField *field = (GIdlNodeField *) node;
-
- const gchar *field_header =
- " {\n"
- " "STRING_POINTER", %d, %d, %d, %d, %d,\n";
-
- fprintf (ctx->mdata_init, field_header,
- ctx->struct_name, g_idl_compiler_write_string (ctx, node->name),
- field->readable, field->writable, 0, 0, field->offset);
-
- /*Insert simple type blob here */
- g_idl_compiler_write_simple_type_blob ((GIdlNode *)field->type, ctx);
-
- fprintf (ctx->mdata_init, " },\n");
-}
-
- /*SIGNAL*/
-/* Used in interface and object */
-static void
-include_signal (GIdlNode * node, GIdlCompilerContext * ctx)
-{
- guint signature_id;
- GIdlNodeSignal *signal = (GIdlNodeSignal *) node;
- const char *signal_header =
- " {\n"
- " %d, %d, %d, %d, %d,\n"
- " %d, %d, %d, %d, %d,\n"
- " 0,\n"
- " %d,\n"
- " "STRING_POINTER",\n"
- " "TYPE_POINTER",\n"
- " },\n";
-
- signature_id = g_idl_compiler_get_unique_id();
-
- g_idl_compiler_push_deferred_signature_node(ctx, node, signature_id);
-
- fprintf(ctx->mdata_init, signal_header,
- signal->deprecated,
- signal->run_first,
- signal->run_last,
- signal->run_cleanup,
- signal->no_recurse,
- signal->detailed,
- signal->action,
- signal->no_hooks,
- 0, /*FIXME*/
- 0, /*FIXME*/
- 0, /*FIXME*/
- ctx->struct_name, g_idl_compiler_write_string (ctx, node->name),
- ctx->struct_name, signature_id);
-}
-
-/*METHOD*/
-/*Used in struct object interface, uses the FunctionBlob*/
-static void
-include_method (GIdlNode * node,
- GIdlCompilerContext * ctx)
-{
- guint signature_id;
- GIdlNodeFunction *function = (GIdlNodeFunction *) node;
- const char *function_header =
- " {\n"
- " %d, %d, %d, %d, %d, %d, 0, %d,\n"
- " "STRING_POINTER",\n"
- " "STRING_POINTER",\n"
- " "TYPE_POINTER",\n"
- " },\n";
-
- signature_id = g_idl_compiler_get_unique_id();
-
- g_idl_compiler_push_deferred_signature_node(ctx, node, signature_id);
-
- fprintf(ctx->mdata_init, function_header,
- BLOB_TYPE_FUNCTION,
- function->deprecated,
- function->is_setter,
- function->is_getter,
- function->is_constructor,
- function->wraps_vfunc,
- 0, /*index??*/
- ctx->struct_name, g_idl_compiler_write_string (ctx, node->name),
- ctx->struct_name, g_idl_compiler_write_string (ctx, function->symbol),
- ctx->struct_name, signature_id);
-}
-
-/*CONSTANT*/
-static void
-include_constant (GIdlNode * node,
- GIdlCompilerContext * ctx)
-{
- GIdlNodeConstant *constant = (GIdlNodeConstant *)node;
- guint entry_id;
- const gchar *constant_header =
- " {\n"
- " %d, %d, 0,\n" /*type/deprecated/reserved */
- " "STRING_POINTER",\n"; /*name */
-
- const gchar *constant_footer =
- " %d, "TYPE_POINTER"\n" /*size/offset*/
- " },\n";
-
- fprintf (ctx->mdata_init, constant_header,
- BLOB_TYPE_CONSTANT,
- constant->deprecated,
- ctx->struct_name, g_idl_compiler_write_string (ctx, node->name));
-
- g_idl_compiler_write_simple_type_blob ((GIdlNode *)constant->type, ctx);
-
- entry_id = g_idl_compiler_get_unique_id();
-
- g_idl_compiler_push_deferred_constant(ctx, node, entry_id);
-
- fprintf (ctx->mdata_init, constant_footer,
- 0, /*FIXME I'm excluding the size, where is this used?*/
- ctx->struct_name, entry_id);
-}
-
-/*ENTRY BLOB COMPILATION*/
-/*----------------------*/
-/* Blobs in this section are given a directory entry
- * and can be used as a type
- */
-
-/*ENUM / FLAGS*/
-static void
-write_enum (GIdlNode * node,
- guint entry_id,
- GIdlCompilerContext * ctx)
-{
- GIdlNodeEnum *enum_ = (GIdlNodeEnum *) node;
- guint16 blob_type;
- guint32 gtype_name = 0;
- guint32 gtype_init = 0;
- guint unregistered;
- GList *c;
-
- const gchar *enum_flags_struct =
- " struct\n"
- " {\n"
- " EnumBlob fixed;\n"
- " ValueBlob values[%d];\n"
- " } " ID_TO_ENTRY ";\n";
-
- const gchar *enum_flags_header =
- " {\n"
- " {\n"
- " %d, %d, %d, %d,\n" /*type/deprecated/unregistered/reserved */
- " " STRING_POINTER ",\n" /*name */
- " " STRING_POINTER ",\n" /*gtype-name */
- " " STRING_POINTER ",\n" /*gtype-init */
- " %d, %d\n" " },\n"; /*n_values/reserved */
-
- if (node->type == G_IDL_NODE_ENUM)
- blob_type = BLOB_TYPE_ENUM;
- else
- blob_type = BLOB_TYPE_FLAGS;
-
- if (enum_->gtype_name)
- {
- unregistered = FALSE;
- gtype_name = g_idl_compiler_write_string (ctx, enum_->gtype_name);
- gtype_init = g_idl_compiler_write_string (ctx, enum_->gtype_init);
- }
- else
- {
- unregistered = TRUE;
- gtype_name = 0;
- gtype_init = 0;
- }
-
- fprintf (ctx->mdata_struct, enum_flags_struct,
- g_list_length (enum_->values), entry_id);
-
- fprintf (ctx->mdata_init, enum_flags_header,
- blob_type,
- enum_->deprecated,
- unregistered,
- 0,
- ctx->struct_name, g_idl_compiler_write_string (ctx, node->name),
- ctx->struct_name, gtype_name,
- ctx->struct_name, gtype_init, g_list_length (enum_->values), 0);
-
- /*Insert value initialisers here */
- fprintf (ctx->mdata_init, " {\n");
- for (c = enum_->values; c; c = c->next)
- {
- include_value (c->data, ctx);
- }
- fprintf (ctx->mdata_init, " },\n");
-
- fprintf (ctx->mdata_init, " },\n\n");
-}
-
-/*FUNCTION*/
-static void
-write_function (GIdlNode * node,
- guint entry_id,
- GIdlCompilerContext * ctx)
-{
- const char *function_struct =
- " FunctionBlob "ID_TO_ENTRY";\n";
-
- fprintf(ctx->mdata_struct, function_struct, entry_id);
-
- include_method(node, ctx);
-}
-
-/*SIGNATURE*/
-static void
-write_signature (GIdlNode * node,
- guint entry_id,
- GIdlCompilerContext * ctx)
-{
- GList *c;
- GIdlNodeFunction *function = (GIdlNodeFunction *) node;
- GIdlNodeVFunc *vfunc = (GIdlNodeVFunc *) node;
- GIdlNodeSignal *signal = (GIdlNodeSignal *) node;
- guint n_args;
- GIdlNodeType *result_type;
- guint null_ok;
- guint transfer;
- guint shallow_transfer;
- GList *param_list;
-
- const char *signature_struct =
- " struct\n"
- " {\n"
- " SignatureBlob fixed;\n"
- " ArgBlob values[%d];\n"
- " } " ID_TO_ENTRY ";\n";
-
- const char *signature_prototype =
- " %d, %d, %d, 0, %d,\n";
-
- switch (node->type)
- {
- case G_IDL_NODE_CALLBACK:
- case G_IDL_NODE_FUNCTION:
- null_ok = function->result->null_ok,
- transfer = function->result->transfer,
- shallow_transfer = function->result->shallow_transfer,
- param_list = function->parameters;
- result_type = function->result->type;
- break;
- case G_IDL_NODE_VFUNC:
- null_ok = vfunc->result->null_ok,
- transfer = vfunc->result->transfer,
- shallow_transfer = vfunc->result->shallow_transfer,
- param_list = vfunc->parameters;
- result_type = vfunc->result->type;
- break;
- case G_IDL_NODE_SIGNAL:
- null_ok = signal->result->null_ok,
- transfer = signal->result->transfer,
- shallow_transfer = signal->result->shallow_transfer,
- param_list = signal->parameters;
- result_type = signal->result->type;
- break;
- default:
- g_assert_not_reached();
- break;
- }
-
- n_args = g_list_length(param_list);
-
- fprintf(ctx->mdata_struct, signature_struct, n_args, entry_id);
-
- fprintf(ctx->mdata_init, " {\n");
- fprintf(ctx->mdata_init, " {\n");
-
- g_idl_compiler_write_simple_type_blob ((GIdlNode *)result_type, ctx);
-
- fprintf(ctx->mdata_init, signature_prototype,
- null_ok,
- transfer,
- shallow_transfer,
- n_args);
-
- fprintf (ctx->mdata_init, " },\n");
-
- /*Write out all the args*/
- fprintf (ctx->mdata_init, " {\n");
- for (c = param_list; c; c = c->next)
- {
- include_param (c->data, ctx);
- }
- fprintf (ctx->mdata_init, " },\n");
-
- fprintf(ctx->mdata_init, " },\n\n");
-}
-
-/*CALLBACK*/
-static void
-write_callback (GIdlNode * node,
- guint entry_id,
- GIdlCompilerContext * ctx)
-{
- guint signature_id;
- GIdlNodeFunction *function = (GIdlNodeFunction *) node;
-
- const char *callback_struct =
- " CallbackBlob "ID_TO_ENTRY";\n";
-
- const char *callback_header =
- " {\n"
- " %d, %d, 0,\n"
- " "STRING_POINTER",\n"
- " "TYPE_POINTER",\n"
- " },\n";
-
- fprintf(ctx->mdata_struct, callback_struct, entry_id);
-
- signature_id = g_idl_compiler_get_unique_id();
-
- g_idl_compiler_push_deferred_signature_node(ctx, node, signature_id);
-
- fprintf(ctx->mdata_init, callback_header,
- BLOB_TYPE_CALLBACK,
- function->deprecated,
- ctx->struct_name, g_idl_compiler_write_string (ctx, node->name),
- ctx->struct_name, signature_id);
-}
-
-/*BOXED*/
-/*TODO merge the boxed and struct functions.*/
-static void
-write_boxed (GIdlNode * node,
- guint entry_id,
- GIdlCompilerContext * ctx)
-{
- GIdlNodeBoxed *boxed = (GIdlNodeBoxed *) node;
- guint16 n_method = 0;
- guint16 n_field = 0;
- GList *l;
-
- const char *struct_struct =
- " struct\n"
- " {\n"
- " StructBlob fixed;\n"
- " FieldBlob fields[%d];\n"
- " FunctionBlob methods[%d];\n"
- " } " ID_TO_ENTRY ";\n";
-
- const gchar *struct_header =
- " {\n"
- " {\n"
- " %d, %d, %d, %d,\n" /*type/deprecated/unregistered/reserved */
- " " STRING_POINTER ",\n" /*name */
- " " STRING_POINTER ",\n" /*gtype-name */
- " " STRING_POINTER ",\n" /*gtype-init */
- " %d, %d\n" /*n_fields/n_methods */
- " },\n"; /*n_values/reserved */
-
- for (l = boxed->members; l; l = l->next)
- {
- GIdlNode *tnode = l->data;
- if (tnode->type == G_IDL_NODE_FIELD)
- {
- n_field++;
- }
- else
- {
- n_method++;
- }
- }
-
- fprintf (ctx->mdata_struct, struct_struct, n_field, n_method, entry_id);
-
- fprintf (ctx->mdata_init, struct_header,
- BLOB_TYPE_STRUCT,
- boxed->deprecated,
- FALSE,
- 0,
- ctx->struct_name, g_idl_compiler_write_string (ctx, node->name),
- ctx->struct_name, g_idl_compiler_write_string (ctx, boxed->gtype_name),
- ctx->struct_name, g_idl_compiler_write_string (ctx, boxed->gtype_init),
- n_field, n_method);
-
- /*Insert field initialisers here */
- fprintf (ctx->mdata_init, " {\n");
- for (l = boxed->members; l; l = l->next)
- {
- GIdlNode *tnode = l->data;
- if (tnode->type == G_IDL_NODE_FIELD)
- include_field (tnode, ctx);
- }
- fprintf (ctx->mdata_init, " },\n");
-
- /*Insert method initialisers here */
- fprintf (ctx->mdata_init, " {\n");
- for (l = boxed->members; l; l = l->next)
- {
- GIdlNode *tnode = l->data;
- if (tnode->type == G_IDL_NODE_FUNCTION)
- include_method (tnode, ctx);
- }
- fprintf (ctx->mdata_init, " },\n");
-
- fprintf (ctx->mdata_init, " },\n\n");
-}
-
-/*STRUCT*/
-static void
-write_struct (GIdlNode * node,
- guint entry_id,
- GIdlCompilerContext * ctx)
-{
- GIdlNodeStruct *struct_ = (GIdlNodeStruct *) node;
- guint16 n_method = 0;
- guint16 n_field = 0;
- GList *l;
-
- const char *struct_struct =
- " struct\n"
- " {\n"
- " StructBlob fixed;\n"
- " FieldBlob fields[%d];\n"
- " FunctionBlob methods[%d];\n"
- " } " ID_TO_ENTRY ";\n";
-
- const gchar *struct_header =
- " {\n"
- " {\n"
- " %d, %d, %d, %d,\n" /*type/deprecated/unregistered/reserved */
- " " STRING_POINTER ",\n" /*name */
- " " STRING_POINTER ",\n" /*gtype-name */
- " " STRING_POINTER ",\n" /*gtype-init */
- " %d, %d\n" /*n_fields/n_methods */
- " },\n"; /*n_values/reserved */
-
- for (l = struct_->members; l; l = l->next)
- {
- GIdlNode *tnode = l->data;
- if (tnode->type == G_IDL_NODE_FIELD)
- {
- n_field++;
- }
- else
- {
- n_method++;
- }
- }
-
- fprintf (ctx->mdata_struct, struct_struct, n_field, n_method, entry_id);
-
- fprintf (ctx->mdata_init, struct_header,
- BLOB_TYPE_STRUCT,
- struct_->deprecated,
- TRUE,
- 0,
- ctx->struct_name, g_idl_compiler_write_string (ctx, node->name),
- ctx->struct_name, 0, ctx->struct_name, 0, n_field, n_method);
-
- /*Insert field initialisers here */
- fprintf (ctx->mdata_init, " {\n");
- for (l = struct_->members; l; l = l->next)
- {
- GIdlNode *tnode = l->data;
- if (tnode->type == G_IDL_NODE_FIELD)
- include_field (tnode, ctx);
- }
- fprintf (ctx->mdata_init, " },\n");
-
- /*Insert method initialisers here */
- fprintf (ctx->mdata_init, " {\n");
- for (l = struct_->members; l; l = l->next)
- {
- GIdlNode *tnode = l->data;
- if (tnode->type == G_IDL_NODE_FUNCTION)
- include_method (tnode, ctx);
- }
- fprintf (ctx->mdata_init, " },\n");
-
- fprintf (ctx->mdata_init, " },\n\n");
-}
-
-/*UNION*/
-static void
-write_union (GIdlNode * node,
- guint entry_id,
- GIdlCompilerContext * ctx)
-{
- GIdlNodeUnion *union_ = (GIdlNodeUnion *)node;
- guint16 n_method = 0;
- guint16 n_field = 0;
- guint16 n_constant = 0;
- gboolean discriminated = FALSE;
- gboolean unregistered = TRUE;
- GList *l;
-
- const char *union_struct =
- " struct\n"
- " {\n"
- " UnionBlob fixed;\n"
- " FieldBlob fields[%d];\n"
- " FunctionBlob methods[%d];\n"
- " ConstantBlob discriminator_values[%d];\n"
- " } " ID_TO_ENTRY ";\n";
-
- const gchar *union_header =
- " {\n"
- " {\n"
- " %d, %d, %d, %d, 0,\n" /*type/deprecated/unregistered/descriminated */
- " " STRING_POINTER ",\n" /*name */
- " " STRING_POINTER ",\n" /*gtype-name */
- " " STRING_POINTER ",\n" /*gtype-init */
- " %d, %d,\n" /*n_fields/n_methods */
- " %d,\n"; /*discriminator_offset*/
-
- for (l = union_->members; l; l = l->next)
- {
- GIdlNode *tnode = l->data;
- if (tnode->type == G_IDL_NODE_FIELD)
- {
- n_field++;
- }
- else
- {
- n_method++;
- }
- }
-
- if (union_->discriminator_type)
- {
- discriminated = TRUE;
- n_constant = g_list_length(union_->discriminators);
- }
-
- if (union_->gtype_name)
- {
- unregistered = FALSE;
- }
-
- fprintf (ctx->mdata_struct, union_struct, n_field, n_method, n_constant, entry_id);
-
- fprintf (ctx->mdata_init, union_header,
- BLOB_TYPE_UNION,
- union_->deprecated,
- unregistered,
- discriminated,
- ctx->struct_name, g_idl_compiler_write_string (ctx, node->name),
- ctx->struct_name, g_idl_compiler_write_string (ctx, union_->gtype_name),
- ctx->struct_name, g_idl_compiler_write_string (ctx, union_->gtype_init),
- n_field, n_method,
- union_->discriminator_offset);
-
- if (discriminated)
- {
- g_idl_compiler_write_simple_type_blob ((GIdlNode *)union_->discriminator_type, ctx);
- }
- else
- {
- fprintf (ctx->mdata_init, " {},\n");
- }
- fprintf (ctx->mdata_init, " },\n");
-
- /*Insert field initialisers here */
- fprintf (ctx->mdata_init, " {\n");
- for (l = union_->members; l; l = l->next)
- {
- GIdlNode *tnode = l->data;
- if (tnode->type == G_IDL_NODE_FIELD)
- include_field (tnode, ctx);
- }
- fprintf (ctx->mdata_init, " },\n");
-
- /*Insert method initialisers here */
- fprintf (ctx->mdata_init, " {\n");
- for (l = union_->members; l; l = l->next)
- {
- GIdlNode *tnode = l->data;
- if (tnode->type == G_IDL_NODE_FUNCTION)
- include_method (tnode, ctx);
- }
- fprintf (ctx->mdata_init, " },\n");
-
- /*Insert discriminators here*/
- fprintf (ctx->mdata_init, " {\n");
- for (l = union_->discriminators; l; l = l->next)
- {
- GIdlNode *tnode = l->data;
- include_constant (tnode, ctx);
- }
- fprintf (ctx->mdata_init, " },\n");
-
- fprintf (ctx->mdata_init, " },\n\n");
-}
-
-/*OBJECT*/
-static void
-write_object (GIdlNode * node,
- guint entry_id,
- GIdlCompilerContext * ctx)
-{
- GIdlNodeInterface *object = (GIdlNodeInterface *) node;
- guint num_interfaces = 0;
- guint num_fields = 0;
- guint num_properties = 0;
- guint num_methods = 0;
- guint num_signals = 0;
- guint num_vfuncs = 0;
- guint num_constants = 0;
-
- GList *l;
-
- const char *object_struct =
- " struct\n"
- " {\n"
- " ObjectBlob fixed;\n"
- " guint16 interfaces[%d];\n"
- " FieldBlob fields[%d];\n"
- " PropertyBlob properties[%d];\n"
- " FunctionBlob methods[%d];\n"
- " SignalBlob signals[%d];\n"
- " VFuncBlob vfuncs[%d];\n"
- " ConstantBlob constants[%d];\n"
- " } " ID_TO_ENTRY ";\n";
-
- const gchar *object_header =
- " {\n"
- " {\n"
- " %d, %d, 0,\n"
- " " STRING_POINTER ",\n"
- " " STRING_POINTER ",\n"
- " " STRING_POINTER ",\n";
-
- const gchar *object_footer =
- " %d, %d, %d, %d, %d, %d, %d,\n"
- " },\n";
-
- const gchar *type_entry =
- " %d,\n";
-
- for (l = object->members; l; l = l->next)
- {
- GIdlNode *tnode = l->data;
- switch (tnode->type)
- {
- case G_IDL_NODE_FIELD:
- num_fields++;
- break;
- case G_IDL_NODE_PROPERTY:
- num_properties++;
- break;
- case G_IDL_NODE_FUNCTION:
- num_methods++;
- break;
- case G_IDL_NODE_SIGNAL:
- num_signals++;
- break;
- case G_IDL_NODE_VFUNC:
- num_vfuncs++;
- break;
- case G_IDL_NODE_CONSTANT:
- num_constants++;
- break;
- default:
- ;
- }
- }
-
- num_interfaces = g_list_length(object->interfaces);
-
- fprintf(ctx->mdata_struct, object_struct,
- num_interfaces,
- num_fields,
- num_properties,
- num_methods,
- num_signals,
- num_vfuncs,
- num_constants,
- entry_id);
-
- fprintf (ctx->mdata_init, object_header,
- BLOB_TYPE_INTERFACE,
- object->deprecated,
- ctx->struct_name, g_idl_compiler_write_string (ctx, node->name),
- ctx->struct_name, g_idl_compiler_write_string (ctx, object->gtype_name),
- ctx->struct_name, g_idl_compiler_write_string (ctx, object->gtype_init));
-
- if (object->parent)
- {
- fprintf(ctx->mdata_init, type_entry,
- g_idl_compiler_get_entry_dirid(ctx, object->parent));
- }
- else
- {
- fprintf (ctx->mdata_init, " 0,\n");
- }
-
- fprintf (ctx->mdata_init, object_footer,
- num_interfaces,
- num_fields,
- num_properties,
- num_methods,
- num_signals,
- num_vfuncs,
- num_constants);
-
- fprintf (ctx->mdata_init, " {\n");
- for (l = object->interfaces; l; l = l->next)
- {
- gchar *interface = l->data;
- fprintf(ctx->mdata_init, type_entry,
- g_idl_compiler_get_entry_dirid(ctx, interface));
- }
- fprintf (ctx->mdata_init, " },\n");
-
- /*Insert fields here*/
- fprintf (ctx->mdata_init, " {\n");
- for (l = object->members; l; l = l->next)
- {
- GIdlNode *tnode = l->data;
- if (tnode->type == G_IDL_NODE_FIELD)
- include_field (tnode, ctx);
- }
- fprintf (ctx->mdata_init, " },\n");
-
- /*Insert properties here*/
- fprintf (ctx->mdata_init, " {\n");
- for (l = object->members; l; l = l->next)
- {
- GIdlNode *tnode = l->data;
- if (tnode->type == G_IDL_NODE_PROPERTY)
- include_property (tnode, ctx);
- }
- fprintf (ctx->mdata_init, " },\n");
-
- /*Insert functions here*/
- fprintf (ctx->mdata_init, " {\n");
- for (l = object->members; l; l = l->next)
- {
- GIdlNode *tnode = l->data;
- if (tnode->type == G_IDL_NODE_FUNCTION)
- include_method (tnode, ctx);
- }
- fprintf (ctx->mdata_init, " },\n");
-
- /*Insert signals here*/
- fprintf (ctx->mdata_init, " {\n");
- for (l = object->members; l; l = l->next)
- {
- GIdlNode *tnode = l->data;
- if (tnode->type == G_IDL_NODE_SIGNAL)
- include_signal (tnode, ctx);
- }
- fprintf (ctx->mdata_init, " },\n");
-
- /*Insert vfuncs here*/
- fprintf (ctx->mdata_init, " {\n");
- for (l = object->members; l; l = l->next)
- {
- GIdlNode *tnode = l->data;
- if (tnode->type == G_IDL_NODE_VFUNC)
- include_vfunc (tnode, ctx);
- }
- fprintf (ctx->mdata_init, " },\n");
-
- /*Insert constants here*/
- fprintf (ctx->mdata_init, " {\n");
- for (l = object->members; l; l = l->next)
- {
- GIdlNode *tnode = l->data;
- if (tnode->type == G_IDL_NODE_CONSTANT)
- include_constant (tnode, ctx);
- }
- fprintf (ctx->mdata_init, " },\n");
-
- fprintf (ctx->mdata_init, " },\n\n");
-}
-
-/*INTERFACE*/
-static void
-write_interface(GIdlNode * node,
- guint entry_id,
- GIdlCompilerContext * ctx)
-{
- GIdlNodeInterface *iface = (GIdlNodeInterface *) node;
- guint num_prerequisites = 0;
- guint num_properties = 0;
- guint num_methods = 0;
- guint num_signals = 0;
- guint num_vfuncs = 0;
- guint num_constants = 0;
-
- GList *l;
-
- const char *interface_struct =
- " struct\n"
- " {\n"
- " InterfaceBlob fixed;\n"
- " guint16 prerequisites[%d];\n"
- " PropertyBlob properties[%d];\n"
- " FunctionBlob methods[%d];\n"
- " SignalBlob signals[%d];\n"
- " VFuncBlob vfuncs[%d];\n"
- " ConstantBlob constants[%d];\n"
- " } " ID_TO_ENTRY ";\n";
-
- const gchar *interface_header =
- " {\n"
- " {\n"
- " %d, %d, 0,\n"
- " " STRING_POINTER ",\n"
- " " STRING_POINTER ",\n"
- " " STRING_POINTER ",\n"
- " %d, %d, %d, %d, %d, %d,\n"
- " },\n";
-
- const gchar *prereq_entry =
- " %d,\n";
-
- for (l = iface->members; l; l = l->next)
- {
- GIdlNode *tnode = l->data;
- switch (tnode->type)
- {
- case G_IDL_NODE_PROPERTY:
- num_properties++;
- break;
- case G_IDL_NODE_FUNCTION:
- num_methods++;
- break;
- case G_IDL_NODE_SIGNAL:
- num_signals++;
- break;
- case G_IDL_NODE_VFUNC:
- num_vfuncs++;
- break;
- case G_IDL_NODE_CONSTANT:
- num_constants++;
- break;
- default:
- ;
- }
- }
-
- num_prerequisites = g_list_length(iface->prerequisites);
-
- fprintf(ctx->mdata_struct, interface_struct,
- num_prerequisites,
- num_properties,
- num_methods,
- num_signals,
- num_vfuncs,
- num_constants,
- entry_id);
-
- fprintf (ctx->mdata_init, interface_header,
- BLOB_TYPE_INTERFACE,
- iface->deprecated,
- ctx->struct_name, g_idl_compiler_write_string (ctx, node->name),
- ctx->struct_name, g_idl_compiler_write_string (ctx, iface->gtype_name),
- ctx->struct_name, g_idl_compiler_write_string (ctx, iface->gtype_init),
- num_prerequisites,
- num_properties,
- num_methods,
- num_signals,
- num_vfuncs,
- num_constants);
-
- fprintf (ctx->mdata_init, " {\n");
- for (l = iface->prerequisites; l; l = l->next)
- {
- gchar *prereq = l->data;
- fprintf(ctx->mdata_init, prereq_entry,
- g_idl_compiler_get_entry_dirid(ctx, prereq));
- }
- fprintf (ctx->mdata_init, " },\n");
-
- /*Insert properties here*/
- fprintf (ctx->mdata_init, " {\n");
- for (l = iface->members; l; l = l->next)
- {
- GIdlNode *tnode = l->data;
- if (tnode->type == G_IDL_NODE_PROPERTY)
- include_property (tnode, ctx);
- }
- fprintf (ctx->mdata_init, " },\n");
-
- /*Insert functions here*/
- fprintf (ctx->mdata_init, " {\n");
- for (l = iface->members; l; l = l->next)
- {
- GIdlNode *tnode = l->data;
- if (tnode->type == G_IDL_NODE_FUNCTION)
- include_method (tnode, ctx);
- }
- fprintf (ctx->mdata_init, " },\n");
-
- /*Insert signals here*/
- fprintf (ctx->mdata_init, " {\n");
- for (l = iface->members; l; l = l->next)
- {
- GIdlNode *tnode = l->data;
- if (tnode->type == G_IDL_NODE_SIGNAL)
- include_signal (tnode, ctx);
- }
- fprintf (ctx->mdata_init, " },\n");
-
- /*Insert vfuncs here*/
- fprintf (ctx->mdata_init, " {\n");
- for (l = iface->members; l; l = l->next)
- {
- GIdlNode *tnode = l->data;
- if (tnode->type == G_IDL_NODE_VFUNC)
- include_vfunc (tnode, ctx);
- }
- fprintf (ctx->mdata_init, " },\n");
-
- /*Insert constants here*/
- fprintf (ctx->mdata_init, " {\n");
- for (l = iface->members; l; l = l->next)
- {
- GIdlNode *tnode = l->data;
- if (tnode->type == G_IDL_NODE_CONSTANT)
- include_constant (tnode, ctx);
- }
- fprintf (ctx->mdata_init, " },\n");
-
- fprintf (ctx->mdata_init, " },\n\n");
-}
-
-/*ERROR DOMAIN*/
-static void
-write_error_domain (GIdlNode * node,
- guint entry_id,
- GIdlCompilerContext * ctx)
-{
- GIdlNodeErrorDomain *domain = (GIdlNodeErrorDomain *) node;
- const char *error_domain_struct =
- " ErrorDomainBlob " ID_TO_ENTRY ";\n";
-
- const gchar *error_domain_header =
- " {\n"
- " %d, %d, 0,\n"
- " " STRING_POINTER ",\n" /*name */
- " " STRING_POINTER ",\n" /*get-quark */
- " " TYPE_POINTER ",\n" /*error-codes*/
- " 0,\n"
- " },\n\n";
-
- fprintf(ctx->mdata_struct, error_domain_struct, entry_id);
-
- fprintf(ctx->mdata_init, error_domain_header,
- BLOB_TYPE_ERROR_DOMAIN,
- domain->deprecated,
- ctx->struct_name, g_idl_compiler_write_string (ctx, node->name),
- ctx->struct_name, g_idl_compiler_write_string (ctx, domain->getquark),
- ctx->struct_name, g_idl_compiler_get_entry_id (ctx, domain->codes));
-}
-
-/*CONSTANT*/
-static void
-write_constant (GIdlNode * node,
- guint entry_id,
- GIdlCompilerContext * ctx)
-{
- const char *constant_struct =
- " ConstantBlob " ID_TO_ENTRY ";\n";
-
- fprintf(ctx->mdata_struct, constant_struct, entry_id);
-
- include_constant(node, ctx);
-}
-
-static void
-write_deferred_constant_values(GIdlCompilerContext *ctx)
-{
- /* TODO there are very few symbols that can be represented
- * as a constant, do we check if something is awry here
- * to prevent errors at compilation time?
- */
- GIdlNodeConstant *constant;
- guint entry_id;
- gchar *type_string;
-
- const char *cvalue_struct =
- " %s " ID_TO_ENTRY ";\n";
-
- const char *cvalue_str_struct =
- " gchar *" ID_TO_ENTRY ";\n";
-
- constant = (GIdlNodeConstant *) g_idl_compiler_pop_deferred_constant(ctx, &entry_id);
- while (constant != NULL)
- {
- fprintf(ctx->mdata_init, " /*Entry - %d*/\n",
- entry_id);
- if (constant->type->tag <= TYPE_TAG_DOUBLE)
- {
- fprintf(ctx->mdata_struct, cvalue_struct,
- g_idl_compiler_name_basic_type(constant->type->tag),
- entry_id);
- fprintf(ctx->mdata_init, " %s,\n",
- constant->value);
- }
- else if (constant->type->tag <= TYPE_TAG_FILENAME)
- {
- fprintf(ctx->mdata_struct, cvalue_str_struct,
- entry_id);
- fprintf(ctx->mdata_init, " \"%s\",\n",
- constant->value);
- }
- else if (constant->type->tag <= TYPE_TAG_SYMBOL)
- {
- GString *str;
- gchar *s;
-
- str = g_string_new (0);
- g_idl_compiler_serialize_type (constant->type, str);
- s = g_string_free (str, FALSE);
-
- fprintf(ctx->mdata_struct, cvalue_struct,
- s,
- entry_id);
- fprintf(ctx->mdata_init, " \"%s\",\n",
- constant->value);
- g_free(s);
- }
- else
- {
- g_warning("Cannot write constant value");
- }
- constant = (GIdlNodeConstant *) g_idl_compiler_pop_deferred_constant(ctx, &entry_id);
- }
-}
-
-static void
-write_deferred_signature_nodes(GIdlCompilerContext *ctx)
-{
- GIdlNode *node;
- guint entry_id;
-
- node = g_idl_compiler_pop_deferred_signature_node(ctx, &entry_id);
- while (node != NULL)
- {
- fprintf(ctx->mdata_init, " /*Entry - %d*/\n",
- entry_id);
- write_signature(node, entry_id, ctx);
- node = g_idl_compiler_pop_deferred_signature_node(ctx, &entry_id);
- }
-}
-
-void
-g_idl_compiler_write_node (GIdlNode * node,
- guint entry_id, GIdlCompilerContext * ctx)
-{
- GList *l;
-
- fprintf(ctx->mdata_init, " /*Entry - %d*/\n",
- entry_id);
-
- switch (node->type)
- {
- case G_IDL_NODE_FUNCTION:
- {
- write_function (node, entry_id, ctx);
- }
- break;
-
- case G_IDL_NODE_CALLBACK:
- {
- write_callback (node, entry_id, ctx);
- }
- break;
-
- case G_IDL_NODE_STRUCT:
- {
- write_struct (node, entry_id, ctx);
- }
- break;
-
- case G_IDL_NODE_BOXED:
- {
- write_boxed (node, entry_id, ctx);
- }
- break;
-
- case G_IDL_NODE_UNION:
- {
- write_union (node, entry_id, ctx);
- }
- break;
-
- case G_IDL_NODE_ENUM:
- case G_IDL_NODE_FLAGS:
- {
- write_enum (node, entry_id, ctx);
- }
- break;
-
- case G_IDL_NODE_OBJECT:
- {
- write_object (node, entry_id, ctx);
- }
- break;
-
- case G_IDL_NODE_INTERFACE:
- {
- write_interface (node, entry_id, ctx);
- }
- break;
-
- case G_IDL_NODE_ERROR_DOMAIN:
- {
- write_error_domain (node, entry_id, ctx);
- }
- break;
-
- case G_IDL_NODE_CONSTANT:
- {
- write_constant (node, entry_id, ctx);
- }
- break;
- default:
- g_assert_not_reached ();
- }
-
- write_deferred_constant_values(ctx);
- write_deferred_signature_nodes(ctx);
- g_idl_compiler_write_deferred_type_blobs(ctx);
-}
+++ /dev/null
-/* GObject introspection: Parsed IDL
- *
- * 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
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __G_IDL_COMP_ENTRY_N_H__
-#define __G_IDL_COMP_ENTRY_N_H__
-
-#include <glib.h>
-
-#include "gidlnode.h"
-#include "gidlcompilercontext.h"
-
-G_BEGIN_DECLS
-
-void
-g_idl_compiler_write_node (GIdlNode * node,
- guint entry_id,
- GIdlCompilerContext * ctx);
-
-G_END_DECLS
-#endif /* __G_IDL_COMP_ENTRY_N_H__ */
+++ /dev/null
-/* GObject introspection: Type node compilation
- *
- * 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
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "gmetadata.h"
-
-#include "gidlnode.h"
-#include "gidlcompilercontext.h"
-#include "gidlcompilertypenode.h"
-
-/*TYPE BLOB COMPILATION*/
-/*---------------------*/
-
-const gchar *
-g_idl_compiler_name_basic_type(guint type_tag)
-{
- const gchar *basic[] = {
- "void",
- "gboolean",
- "gint8",
- "guint8",
- "gint16",
- "guint16",
- "gint32",
- "guint32",
- "gint64",
- "guint64",
- "gint",
- "guint",
- "glong",
- "gulong",
- "gssize",
- "gsize",
- "gfloat",
- "gdouble",
- "utf8",
- "filename"
- };
-
- return basic[type_tag];
-}
-
-void
-g_idl_compiler_serialize_type (GIdlNodeType * node, GString * str)
-{
- gint i;
-
- if (TYPE_IS_SIMPLE(node->tag))
- {
- g_string_append_printf (str, "%s%s",
- g_idl_compiler_name_basic_type(node->tag),
- node->is_pointer ? "*" : "");
- }
- else if (node->tag == TYPE_TAG_ARRAY)
- {
- g_idl_compiler_serialize_type (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 == TYPE_TAG_SYMBOL)
- {
- g_string_append_printf (str, "%s%s", node->interface,
- node->is_pointer ? "*" : "");
- }
- else if (node->tag == TYPE_TAG_LIST)
- {
- g_string_append (str, "GList");
- if (node->parameter_type1)
- {
- g_string_append (str, "<");
- g_idl_compiler_serialize_type (node->parameter_type1, str);
- g_string_append (str, ">");
- }
- }
- else if (node->tag == TYPE_TAG_SLIST)
- {
- g_string_append (str, "GSList");
- if (node->parameter_type1)
- {
- g_string_append (str, "<");
- g_idl_compiler_serialize_type (node->parameter_type1, str);
- g_string_append (str, ">");
- }
- }
- else if (node->tag == TYPE_TAG_HASH)
- {
- g_string_append (str, "GHashTable<");
- if (node->parameter_type1)
- {
- g_string_append (str, "<");
- g_idl_compiler_serialize_type (node->parameter_type1, str);
- g_string_append (str, ",");
- g_idl_compiler_serialize_type (node->parameter_type2, str);
- g_string_append (str, ">");
- }
- }
- else if (node->tag == TYPE_TAG_ERROR)
- {
- 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, ">");
- }
- }
-}
-
-/* Types below somewhat augment a more basic type that has
- * an entry in the direcory. An array type is an array of X.
- * A list is a list of X.
- */
-static void
-type_array_write (GIdlNode * node,
- guint type_id, GIdlCompilerContext * ctx)
-{
- GIdlNodeType *type = (GIdlNodeType *) node;
-
- const gchar *array_struct =
- " ArrayTypeBlob "ID_TO_ENTRY";\n";
-
- const gchar *array_initialiser =
- " {\n"
- " {%d, 0, %d},\n"
- " %d, %d, 0, %d,\n";
-
- fprintf(ctx->mdata_struct, array_struct, type_id);
-
- fprintf(ctx->mdata_init, array_initialiser,
- 1,
- type->tag,
- type->zero_terminated,
- type->has_length,
- type->length);
-
- g_idl_compiler_write_simple_type_blob ((GIdlNode*)type->parameter_type1, ctx);
-
- fprintf(ctx->mdata_init, " },\n\n");
-}
-
-static void
-type_list_write (GIdlNode * node,
- guint type_id,
- GIdlCompilerContext * ctx)
-{
- GIdlNodeType *type = (GIdlNodeType *) node;
- guint n_types = 1;
-
- const gchar *array_struct =
- " struct {\n"
- " ParamTypeBlob fixed;\n"
- " SimpleTypeBlob type[%d];\n"
- " } "ID_TO_ENTRY";\n";
-
- const gchar *array_initialiser =
- " {\n"
- " {\n"
- " {%d, 0, %d},\n"
- " 0, %d,\n"
- " },\n";
-
- fprintf(ctx->mdata_struct, array_struct, n_types, type_id);
-
- fprintf(ctx->mdata_init, array_initialiser,
- 1,
- type->tag,
- n_types);
-
- fprintf(ctx->mdata_init, " {\n");
- if (type->parameter_type1)
- {
- g_idl_compiler_write_simple_type_blob ((GIdlNode*)type->parameter_type1, ctx);
- }
- fprintf(ctx->mdata_init, " },\n");
-
- fprintf(ctx->mdata_init, " },\n\n");
-}
-
-static void
-type_hash_write (GIdlNode * node,
- guint type_id, GIdlCompilerContext * ctx)
-{
- GIdlNodeType *type = (GIdlNodeType *) node;
- guint n_types = 2;
-
- const gchar *hash_struct =
- " struct {\n"
- " ParamTypeBlob fixed;\n"
- " SimpleTypeBlob type[%d];\n"
- " } "ID_TO_ENTRY";\n";
-
- const gchar *hash_initialiser =
- " {\n"
- " {\n"
- " {%d, 0, %d},\n"
- " 0, %d,\n"
- " },\n";
-
- fprintf(ctx->mdata_struct, hash_struct, n_types, type_id);
-
- fprintf(ctx->mdata_init, hash_initialiser,
- 1,
- type->tag,
- n_types);
-
- fprintf(ctx->mdata_init, " {\n");
- if (type->parameter_type1)
- {
- g_idl_compiler_write_simple_type_blob ((GIdlNode*)type->parameter_type1, ctx);
- }
- if (type->parameter_type2)
- {
- g_idl_compiler_write_simple_type_blob ((GIdlNode*)type->parameter_type2, ctx);
- }
- fprintf(ctx->mdata_init, " },\n");
-
- fprintf(ctx->mdata_init, " },\n\n");
-}
-
-static void
-type_error_write (GIdlNode * node,
- guint type_id, GIdlCompilerContext * ctx)
-{
- GIdlNodeType *type = (GIdlNodeType *) node;
- guint n_domains = 0;
- guint i;
-
- const gchar *error_struct =
- " struct {\n"
- " ErrorTypeBlob fixed;\n"
- " guint16 domains[%d];\n"
- " } "ID_TO_ENTRY";\n";
-
- const gchar *error_initialiser =
- " {\n"
- " {\n"
- " {%d, 0, %d},\n"
- " %d,\n"
- " },\n";
-
- const gchar *error_domain_entry =
- " %d,\n";
-
- if (type->errors)
- {
- n_domains = g_strv_length(type->errors);
- }
-
- fprintf(ctx->mdata_struct, error_struct, n_domains, type_id);
-
- fprintf(ctx->mdata_init, error_initialiser,
- 1,
- type->tag,
- n_domains);
-
- fprintf(ctx->mdata_init, " {\n");
- for (i=0; i < n_domains; i++)
- {
- fprintf(ctx->mdata_init, error_domain_entry,
- g_idl_compiler_get_entry_dirid (ctx, type->errors[i]));
- }
- fprintf(ctx->mdata_init, " },\n");
-
- fprintf(ctx->mdata_init, " },\n\n");
-}
-
-static void
-type_complex_write (GIdlNode * node,
- guint type_id, GIdlCompilerContext * ctx)
-{
- GIdlNodeType *type = (GIdlNodeType *) node;
-
- switch (type->tag)
- {
- case TYPE_TAG_ARRAY:
- {
- type_array_write (node, type_id, ctx);
- }
- break;
-
- case TYPE_TAG_LIST:
- case TYPE_TAG_SLIST:
- {
- type_list_write (node, type_id, ctx);
- }
- break;
-
- case TYPE_TAG_HASH:
- {
- type_hash_write (node, type_id, ctx);
- }
- break;
-
- case TYPE_TAG_ERROR:
- {
- type_error_write (node, type_id, ctx);
- }
- break;
-
- default:
- g_error ("Unknown type tag %d\n", type->tag);
- break;
- }
-}
-
-/* This is called at the end of any entries that may have
- * added complex type blobs to the type list.
- *
- * These can only be written out to the metadata at the end of a previous
- * entry and so are deffered until the entry is finished.
- */
-void
-g_idl_compiler_write_deferred_type_blobs (GIdlCompilerContext *ctx)
-{
- GIdlNodeType *type;
- guint entry_id;
- type = (GIdlNodeType *) g_idl_compiler_pop_deferred_type_node (ctx, &entry_id);
-
- while (type)
- {
- fprintf(ctx->mdata_init, " /*Entry - %d*/\n",
- entry_id);
- type_complex_write ((GIdlNode *) type, entry_id, ctx);
- type = (GIdlNodeType *) g_idl_compiler_pop_deferred_type_node (ctx, &entry_id);
- }
-}
-
-/*
- * This function writes out a simple type blob initializer.
- * Simple type blobs are only included in other entries.
- */
-void
-g_idl_compiler_write_simple_type_blob (GIdlNode * node, GIdlCompilerContext * ctx)
-{
- GIdlNodeType *type = (GIdlNodeType *) node;
-
- const gchar *simple_initialiser =
- " {\n"
- " {%d, 0, %d}, 0\n"
- " },\n";
- const gchar *symbol_initialiser =
- " {\n"
- " {%d, 0, %d}, %d,\n"
- " },\n";
- const gchar *complex_initialiser =
- " {\n"
- " {%d, 0, %d}, "TYPE_POINTER",\n"
- " },\n";
-
- /* If this is a simple type */
- /* Simple types are not given their own entry
- * into the global structure. They are a member of
- * another entry.
- */
- if (TYPE_IS_SIMPLE(type->tag))
- {
- fprintf (ctx->mdata_init, simple_initialiser,
- type->is_pointer, type->tag);
- }
- else if (TYPE_IS_SYMBOL(type->tag))
- {
- guint dir_id;
-
- dir_id = g_idl_compiler_get_entry_dirid(ctx, type->interface);
-
- fprintf (ctx->mdata_init, symbol_initialiser,
- type->is_pointer, type->tag,
- dir_id);
- }
- else
- {
- gpointer type_id;
- GString *str;
- gchar *s;
-
- str = g_string_new (0);
- g_idl_compiler_serialize_type (type, str);
- s = g_string_free (str, FALSE);
-
- type_id = g_hash_table_lookup (ctx->typesdb, s);
- if (type_id)
- {
- g_free (s);
- }
- else
- {
- type_id = GINT_TO_POINTER (g_idl_compiler_get_unique_id ());
- g_hash_table_insert (ctx->typesdb, s, type_id);
- g_idl_compiler_push_deferred_type_node (ctx, node, GPOINTER_TO_INT(type_id));
- }
-
- fprintf (ctx->mdata_init, complex_initialiser,
- type->is_pointer, type->tag,
- ctx->struct_name, GPOINTER_TO_INT(type_id));
- }
-}
+++ /dev/null
-/* GObject introspection: Parsed IDL
- *
- * 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
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __G_IDL_COMP_TYPE_N_H__
-#define __G_IDL_COMP_TYPE_N_H__
-
-#include <glib.h>
-
-#include "gidlnode.h"
-#include "gidlcompilercontext.h"
-
-G_BEGIN_DECLS
-
-const gchar *
-g_idl_compiler_name_basic_type(guint type_tag);
-
-void
-g_idl_compiler_serialize_type (GIdlNodeType * node, GString * str);
-
-void
-g_idl_compiler_write_deferred_type_blobs (GIdlCompilerContext *ctx);
-
-void
-g_idl_compiler_write_simple_type_blob (GIdlNode * node, GIdlCompilerContext * ctx);
-
-G_END_DECLS
-#endif /* __G_IDL_COMP_TYPE_N_H__ */
/* 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
#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);
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);
+}
+
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__ */
#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)
{
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)
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;
+}
+
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);
}
else
{
- type->tag = TYPE_TAG_SYMBOL;
+ type->tag = TYPE_TAG_INTERFACE;
type->is_interface = TRUE;
start = *rest;
+++ /dev/null
-#!/bin/sh
-
-cat $1 | sed -e '1 i\const char gmetadata_header[] =\n' -e 's/\\/\\\\/g' -e 's/\"/\\\"/g' -e 's/.*/\"&\\n\"/' -e '$ a\;' > $2