From 39e94bfbcd3e7df3f74b16174e88eff6a19856e0 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Tue, 22 Apr 2008 22:48:16 +0000 Subject: [PATCH] Revert revisions 157,149-148,136-129 and 120. Move back to using 2008-04-22 Johan Dahlin * 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. svn path=/trunk/; revision=214 --- ChangeLog | 50 ++ girepository/ginfo.c | 335 ++++--- girepository/ginvoke.c | 2 +- girepository/girepository.h | 5 +- girepository/gmetadata.c | 190 +++- girepository/gmetadata.h | 79 +- tests/Makefile.am | 9 +- tests/invoke/Makefile.am | 17 +- tests/invoke/invoke-namespace-find.sh | 4 + tests/invoke/invoke.c | 21 +- tests/roundtrips.sh | 32 +- tools/Makefile.am | 17 +- tools/compiler.c | 231 +++-- tools/generate.c | 55 +- tools/gidlcompilercontext.c | 668 -------------- tools/gidlcompilercontext.h | 131 --- tools/gidlcompilerentrynode.c | 1266 --------------------------- tools/gidlcompilerentrynode.h | 37 - tools/gidlcompilertypenode.c | 430 --------- tools/gidlcompilertypenode.h | 44 - tools/gidlmodule.c | 161 +++- tools/gidlmodule.h | 3 + tools/gidlnode.c | 1557 +++++++++++++++++++++++++++++++++ tools/gidlnode.h | 15 +- tools/gidlparser.c | 2 +- tools/quote-file.sh | 3 - 26 files changed, 2353 insertions(+), 3011 deletions(-) create mode 100755 tests/invoke/invoke-namespace-find.sh delete mode 100644 tools/gidlcompilercontext.c delete mode 100644 tools/gidlcompilercontext.h delete mode 100644 tools/gidlcompilerentrynode.c delete mode 100644 tools/gidlcompilerentrynode.h delete mode 100644 tools/gidlcompilertypenode.c delete mode 100644 tools/gidlcompilertypenode.h delete mode 100755 tools/quote-file.sh diff --git a/ChangeLog b/ChangeLog index 03694ef..b6d264a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,53 @@ +2008-04-22 Johan Dahlin + + * 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 * giscanner/girwriter.py: diff --git a/girepository/ginfo.c b/girepository/ginfo.c index 9349611..6d66de2 100644 --- a/girepository/ginfo.c +++ b/girepository/ginfo.c @@ -161,35 +161,29 @@ g_info_from_entry (GMetadata *metadata, { GIBaseInfo *result; DirEntry *entry = g_metadata_get_dir_entry (metadata, index); - + if (entry->local) result = g_info_new (entry->blob_type, NULL, metadata, entry->offset); - else + else { - const gchar *namespace = NULL; - const gchar *name = NULL; + const gchar *namespace = g_metadata_get_string (metadata, entry->offset); + const gchar *name = g_metadata_get_string (metadata, entry->name); + GIRepository *repository = g_irepository_get_default (); - - namespace = g_metadata_get_string (metadata, entry->offset); - name = g_metadata_get_string (metadata, entry->name); - + result = g_irepository_find_by_name (repository, namespace, name); if (result == NULL) { GIUnresolvedInfo *unresolved; + unresolved = g_new0 (GIUnresolvedInfo, 1); + unresolved->type = GI_INFO_TYPE_UNRESOLVED; unresolved->ref_count = 1; unresolved->container = NULL; unresolved->name = name; - if (entry->offset) - { - unresolved->namespace = namespace; - } - else - { - unresolved->namespace = NULL; - } + unresolved->namespace = namespace; + result = (GIBaseInfo*)unresolved; } } @@ -534,27 +528,15 @@ signature_offset (GICallableInfo *info) return 0; } -/* Type blobs when created always point to a SimpleTypeBlob, - * If the type tag means that the type needs to be complex then - * the SimpleTypeBlob has an offset which points to the real type. - */ GITypeInfo * g_type_info_new (GIBaseInfo *container, GMetadata *metadata, guint32 offset) { - TypeHeader *header; - SimpleTypeBlob *simple; - - header = (TypeHeader *)&metadata->data[offset]; - if (TYPE_IS_COMPLEX (header->tag)) - { - simple = (SimpleTypeBlob *)&metadata->data[offset]; - offset = simple->offset; - } + SimpleTypeBlob *type = (SimpleTypeBlob *)&metadata->data[offset]; - return (GITypeInfo*)g_info_new (GI_INFO_TYPE_TYPE, container, - metadata, offset); + return (GITypeInfo *) g_info_new (GI_INFO_TYPE_TYPE, container, metadata, + type->reserved == 0 ? offset : type->offset); } /** @@ -739,18 +721,32 @@ gboolean g_type_info_is_pointer (GITypeInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - TypeHeader *header = (TypeHeader *)&base->metadata->data[base->offset]; - - return header->pointer != 0; + SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset]; + + if (type->reserved == 0) + return type->pointer; + else + { + InterfaceTypeBlob *iface = (InterfaceTypeBlob *)&base->metadata->data[base->offset]; + + return iface->pointer; + } } GITypeTag g_type_info_get_tag (GITypeInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - TypeHeader *header = (TypeHeader *)&base->metadata->data[base->offset]; + SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset]; + + if (type->reserved == 0) + return type->tag; + else + { + InterfaceTypeBlob *iface = (InterfaceTypeBlob *)&base->metadata->data[base->offset]; - return header->tag; + return iface->tag; + } } GITypeInfo * @@ -758,39 +754,42 @@ g_type_info_get_param_type (GITypeInfo *info, gint n) { GIBaseInfo *base = (GIBaseInfo *)info; - TypeHeader *header = (TypeHeader *)&base->metadata->data[base->offset]; - ParamTypeBlob *param = (ParamTypeBlob *)&base->metadata->data[base->offset]; - - switch (header->tag) + SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset]; + + if (type->reserved != 0) { - case TYPE_TAG_ARRAY: - case TYPE_TAG_LIST: - case TYPE_TAG_SLIST: - case TYPE_TAG_HASH: - { - guint32 offset = base->offset + sizeof(ParamTypeBlob) + - (sizeof(SimpleTypeBlob)* n); - return g_type_info_new (base, base->metadata, offset); - } - default: - return NULL; - } + ParamTypeBlob *param = (ParamTypeBlob *)&base->metadata->data[base->offset]; - g_assert_not_reached (); + switch (param->tag) + { + case GI_TYPE_TAG_ARRAY: + case GI_TYPE_TAG_GLIST: + case GI_TYPE_TAG_GSLIST: + case GI_TYPE_TAG_GHASH: + return g_type_info_new (base, base->metadata, base->offset + 4 + 4 * n); + break; + + default: ; + } + } + + return NULL; } GIBaseInfo * g_type_info_get_interface (GITypeInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - TypeHeader *header = (TypeHeader *)&base->metadata->data[base->offset]; - SimpleTypeBlob *simple = (SimpleTypeBlob *)&base->metadata->data[base->offset]; - - if (header->tag == TYPE_TAG_SYMBOL) + SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset]; + + if (type->reserved != 0) { - CommonBlob *common = (CommonBlob *)&base->metadata->data[simple->offset]; - return g_info_from_entry (base->metadata, simple->offset); + InterfaceTypeBlob *blob = (InterfaceTypeBlob *)&base->metadata->data[base->offset]; + + if (blob->tag == GI_TYPE_TAG_INTERFACE) + return g_info_from_entry (base->metadata, blob->interface); } + return NULL; } @@ -798,13 +797,19 @@ gint g_type_info_get_array_length (GITypeInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - TypeHeader *header = (TypeHeader *)&base->metadata->data[base->offset]; - ArrayTypeBlob *array = (ArrayTypeBlob *)&base->metadata->data[base->offset]; - - if (header->tag == TYPE_TAG_ARRAY && array->has_length) + SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset]; + + if (type->reserved != 0) { - return array->length; + ArrayTypeBlob *blob = (ArrayTypeBlob *)&base->metadata->data[base->offset]; + + if (blob->tag == GI_TYPE_TAG_ARRAY) + { + if (blob->has_length) + return blob->length; + } } + return -1; } @@ -812,24 +817,33 @@ gboolean g_type_info_is_zero_terminated (GITypeInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - TypeHeader *header = (TypeHeader *)&base->metadata->data[base->offset]; - ArrayTypeBlob *array = (ArrayTypeBlob *)&base->metadata->data[base->offset]; + SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset]; + + if (type->reserved != 0) + { + ArrayTypeBlob *blob = (ArrayTypeBlob *)&base->metadata->data[base->offset]; - return (header->tag == TYPE_TAG_ARRAY && - array->zero_terminated); + if (blob->tag == GI_TYPE_TAG_ARRAY) + return blob->zero_terminated; + } + + return FALSE; } gint g_type_info_get_n_error_domains (GITypeInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - TypeHeader *header = (TypeHeader *)&base->metadata->data[base->offset]; - ErrorTypeBlob *error = (ErrorTypeBlob *)&base->metadata->data[base->offset]; - - if (header->tag == TYPE_TAG_ERROR) + SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset]; + + if (type->reserved != 0) { - return error->n_domains; + ErrorTypeBlob *blob = (ErrorTypeBlob *)&base->metadata->data[base->offset]; + + if (blob->tag == GI_TYPE_TAG_ERROR) + return blob->n_domains; } + return 0; } @@ -838,16 +852,17 @@ g_type_info_get_error_domain (GITypeInfo *info, gint n) { GIBaseInfo *base = (GIBaseInfo *)info; - TypeHeader *header = (TypeHeader *)&base->metadata->data[base->offset]; - ErrorTypeBlob *error = (ErrorTypeBlob *)&base->metadata->data[base->offset]; - guint16 *domain; - - if (header->tag == TYPE_TAG_ERROR) + SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset]; + + if (type->reserved != 0) { - domain = (guint16*) (&base->metadata->data[base->offset + sizeof(ErrorTypeBlob)]); - return (GIErrorDomainInfo *) g_info_from_entry (base->metadata, - domain[n]); + ErrorTypeBlob *blob = (ErrorTypeBlob *)&base->metadata->data[base->offset]; + + if (blob->tag == GI_TYPE_TAG_ERROR) + return (GIErrorDomainInfo *) g_info_from_entry (base->metadata, + blob->domains[n]); } + return NULL; } @@ -866,13 +881,9 @@ GIInterfaceInfo * g_error_domain_info_get_codes (GIErrorDomainInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - ErrorDomainBlob *blob = (ErrorDomainBlob *)&base->metadata->data[base->offset]; - - /* FIXME need to check if blob really is an enum */ - return (GIInterfaceInfo *) g_info_new (BLOB_TYPE_ENUM, - NULL, - base->metadata, - blob->error_codes); + ErrorDomainBlob *blob = (ErrorDomainBlob *)&base->metadata->data[base->offset]; + + return (GIInterfaceInfo *) g_info_from_entry (base->metadata, blob->error_codes); } @@ -999,8 +1010,8 @@ g_struct_info_get_method (GIStructInfo *info, gint offset; offset = base->offset + header->struct_blob_size - + blob->n_fields * header->field_blob_size - + n * header->function_blob_size; + + blob->n_fields * header->field_blob_size + + n * header->function_blob_size; return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, base, base->metadata, offset); } @@ -1054,15 +1065,6 @@ g_enum_info_get_n_values (GIEnumInfo *info) return blob->n_values; } -gboolean -g_enum_info_is_registered (GIEnumInfo *info) -{ - GIBaseInfo *base = (GIBaseInfo *)info; - EnumBlob *blob = (EnumBlob *)&base->metadata->data[base->offset]; - - return !blob->unregistered; -} - GIValueInfo * g_enum_info_get_value (GIEnumInfo *info, gint n) @@ -1073,8 +1075,7 @@ g_enum_info_get_value (GIEnumInfo *info, offset = base->offset + header->enum_blob_size + n * header->value_blob_size; - return (GIValueInfo *) g_info_new (GI_INFO_TYPE_VALUE, base, - base->metadata, offset); + return (GIValueInfo *) g_info_new (GI_INFO_TYPE_VALUE, base, base->metadata, offset); } /* GIObjectInfo functions */ @@ -1123,11 +1124,8 @@ g_object_info_get_interface (GIObjectInfo *info, { GIBaseInfo *base = (GIBaseInfo *)info; ObjectBlob *blob = (ObjectBlob *)&base->metadata->data[base->offset]; - guint16 *interface; - interface = (guint16 *)&base->metadata->data[base->offset + sizeof(ObjectBlob)]; - - return (GIInterfaceInfo *) g_info_from_entry (base->metadata, interface[n]); + return (GIInterfaceInfo *) g_info_from_entry (base->metadata, blob->interfaces[n]); } gint @@ -1152,8 +1150,7 @@ g_object_info_get_field (GIObjectInfo *info, + (blob->n_interfaces + blob->n_interfaces % 2) * 2 + n * header->field_blob_size; - return (GIFieldInfo *) g_info_new (GI_INFO_TYPE_FIELD, base, - base->metadata, offset); + return (GIFieldInfo *) g_info_new (GI_INFO_TYPE_FIELD, base, base->metadata, offset); } gint @@ -1335,11 +1332,8 @@ g_interface_info_get_prerequisite (GIInterfaceInfo *info, { GIBaseInfo *base = (GIBaseInfo *)info; InterfaceBlob *blob = (InterfaceBlob *)&base->metadata->data[base->offset]; - guint16 *prerequisite; - - prerequisite = (guint16 *)&base->metadata->data[base->offset + sizeof(InterfaceBlob)]; - return g_info_from_entry (base->metadata, prerequisite[n]); + return g_info_from_entry (base->metadata, blob->prerequisites[n]); } @@ -1578,8 +1572,7 @@ g_signal_info_get_class_closure (GISignalInfo *info) SignalBlob *blob = (SignalBlob *)&base->metadata->data[base->offset]; if (blob->has_class_closure) - return g_interface_info_get_vfunc ((GIInterfaceInfo *)base->container, - blob->class_closure); + return g_interface_info_get_vfunc ((GIInterfaceInfo *)base->container, blob->class_closure); return NULL; } @@ -1653,67 +1646,63 @@ g_constant_info_get_value (GIConstantInfo *info, { GIBaseInfo *base = (GIBaseInfo *)info; ConstantBlob *blob = (ConstantBlob *)&base->metadata->data[base->offset]; - TypeHeader *header = (TypeHeader*) &blob->type; - if (TYPE_IS_SIMPLE (header->tag)) - { - switch (header->tag) - { - case GI_TYPE_TAG_BOOLEAN: - value->v_boolean = *(gboolean*)&base->metadata->data[blob->offset]; - break; - case GI_TYPE_TAG_INT8: - value->v_int8 = *(gint8*)&base->metadata->data[blob->offset]; - break; - case GI_TYPE_TAG_UINT8: - value->v_uint8 = *(guint8*)&base->metadata->data[blob->offset]; - break; - case GI_TYPE_TAG_INT16: - value->v_int16 = *(gint16*)&base->metadata->data[blob->offset]; - break; - case GI_TYPE_TAG_UINT16: - value->v_uint16 = *(guint16*)&base->metadata->data[blob->offset]; - break; - case GI_TYPE_TAG_INT32: - value->v_int32 = *(gint32*)&base->metadata->data[blob->offset]; - break; - case GI_TYPE_TAG_UINT32: - value->v_uint32 = *(guint32*)&base->metadata->data[blob->offset]; - break; - case GI_TYPE_TAG_INT64: - value->v_int64 = *(gint64*)&base->metadata->data[blob->offset]; - break; - case GI_TYPE_TAG_UINT64: - value->v_uint64 = *(guint64*)&base->metadata->data[blob->offset]; - break; - case GI_TYPE_TAG_FLOAT: - value->v_float = *(gfloat*)&base->metadata->data[blob->offset]; - break; - case GI_TYPE_TAG_DOUBLE: - value->v_double = *(gdouble*)&base->metadata->data[blob->offset]; - break; - case GI_TYPE_TAG_INT: - value->v_int = *(gint*)&base->metadata->data[blob->offset]; - break; - case GI_TYPE_TAG_UINT: - value->v_uint = *(guint*)&base->metadata->data[blob->offset]; - break; - case GI_TYPE_TAG_LONG: - value->v_long = *(glong*)&base->metadata->data[blob->offset]; - break; - case GI_TYPE_TAG_ULONG: - value->v_ulong = *(gulong*)&base->metadata->data[blob->offset]; - break; - } - } - else + /* FIXME non-basic types ? */ + if (blob->type.reserved == 0) { - switch (header->tag) - { - case GI_TYPE_TAG_SYMBOL: - value->v_string = *(gchar**)&base->metadata->data[blob->offset]; - break; - } + if (blob->type.pointer) + value->v_pointer = g_memdup (&base->metadata->data[blob->offset], blob->size); + else + { + switch (blob->type.tag) + { + case GI_TYPE_TAG_BOOLEAN: + value->v_boolean = *(gboolean*)&base->metadata->data[blob->offset]; + break; + case GI_TYPE_TAG_INT8: + value->v_int8 = *(gint8*)&base->metadata->data[blob->offset]; + break; + case GI_TYPE_TAG_UINT8: + value->v_uint8 = *(guint8*)&base->metadata->data[blob->offset]; + break; + case GI_TYPE_TAG_INT16: + value->v_int16 = *(gint16*)&base->metadata->data[blob->offset]; + break; + case GI_TYPE_TAG_UINT16: + value->v_uint16 = *(guint16*)&base->metadata->data[blob->offset]; + break; + case GI_TYPE_TAG_INT32: + value->v_int32 = *(gint32*)&base->metadata->data[blob->offset]; + break; + case GI_TYPE_TAG_UINT32: + value->v_uint32 = *(guint32*)&base->metadata->data[blob->offset]; + break; + case GI_TYPE_TAG_INT64: + value->v_int64 = *(gint64*)&base->metadata->data[blob->offset]; + break; + case GI_TYPE_TAG_UINT64: + value->v_uint64 = *(guint64*)&base->metadata->data[blob->offset]; + break; + case GI_TYPE_TAG_FLOAT: + value->v_float = *(gfloat*)&base->metadata->data[blob->offset]; + break; + case GI_TYPE_TAG_DOUBLE: + value->v_double = *(gdouble*)&base->metadata->data[blob->offset]; + break; + case GI_TYPE_TAG_INT: + value->v_int = *(gint*)&base->metadata->data[blob->offset]; + break; + case GI_TYPE_TAG_UINT: + value->v_uint = *(guint*)&base->metadata->data[blob->offset]; + break; + case GI_TYPE_TAG_LONG: + value->v_long = *(glong*)&base->metadata->data[blob->offset]; + break; + case GI_TYPE_TAG_ULONG: + value->v_ulong = *(gulong*)&base->metadata->data[blob->offset]; + break; + } + } } return blob->size; @@ -1814,4 +1803,4 @@ g_union_info_get_discriminator (GIUnionInfo *info, } return NULL; -} +} diff --git a/girepository/ginvoke.c b/girepository/ginvoke.c index 6324536..986ca78 100644 --- a/girepository/ginvoke.c +++ b/girepository/ginvoke.c @@ -100,8 +100,8 @@ get_ffi_type (GITypeInfo *info) 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: diff --git a/girepository/girepository.h b/girepository/girepository.h index 0c1ac66..7ad1067 100644 --- a/girepository/girepository.h +++ b/girepository/girepository.h @@ -277,8 +277,8 @@ typedef enum { GI_TYPE_TAG_DOUBLE = 17, GI_TYPE_TAG_UTF8 = 18, GI_TYPE_TAG_FILENAME = 19, - GI_TYPE_TAG_SYMBOL = 20, - GI_TYPE_TAG_ARRAY = 21, + GI_TYPE_TAG_ARRAY = 20, + GI_TYPE_TAG_INTERFACE = 21, GI_TYPE_TAG_GLIST = 22, GI_TYPE_TAG_GSLIST = 23, GI_TYPE_TAG_GHASH = 24, @@ -355,7 +355,6 @@ const gchar * g_registered_type_info_get_type_init (GIRegisteredTypeInf /* 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); diff --git a/girepository/gmetadata.c b/girepository/gmetadata.c index 8c98270..b680390 100644 --- a/girepository/gmetadata.c +++ b/girepository/gmetadata.c @@ -30,11 +30,6 @@ #define ALIGN_VALUE(this, boundary) \ (( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1))) -static gboolean -validate_blob (GMetadata *metadata, - guint32 offset, - GError **error); - DirEntry * g_metadata_get_dir_entry (GMetadata *metadata, @@ -42,9 +37,41 @@ 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) { @@ -124,6 +151,32 @@ validate_header (GMetadata *metadata, return FALSE; } + if (header->entry_blob_size != 12 || + header->function_blob_size != 16 || + header->callback_blob_size != 12 || + header->signal_blob_size != 12 || + header->vfunc_blob_size != 16 || + header->arg_blob_size != 12 || + header->property_blob_size != 12 || + header->field_blob_size != 12 || + header->value_blob_size != 12 || + header->constant_blob_size != 20 || + header->error_domain_blob_size != 16 || + header->annotation_blob_size != 12 || + header->signature_blob_size != 8 || + header->enum_blob_size != 20 || + header->struct_blob_size != 20 || + header->object_blob_size != 32 || + header->interface_blob_size != 28 || + header->union_blob_size != 28) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_HEADER, + "Blob size mismatch"); + return FALSE; + } + if (!is_aligned (header->directory)) { g_set_error (error, @@ -176,16 +229,17 @@ validate_array_type_blob (GMetadata *metadata, gboolean return_type, GError **error) { - ArrayTypeBlob *blob = (ArrayTypeBlob*)&metadata->data[offset]; - TypeHeader *header = (TypeHeader *)&metadata->data[offset]; + ArrayTypeBlob *blob; - if (!header->pointer) + blob = (ArrayTypeBlob*)&metadata->data[offset]; + + if (!blob->pointer) { g_set_error (error, G_METADATA_ERROR, G_METADATA_ERROR_INVALID_BLOB, - "Pointer type exected for tag %d", header->tag); - return FALSE; + "Pointer type exected for tag %d", blob->tag); + return FALSE; } /* FIXME validate length */ @@ -199,6 +253,32 @@ validate_array_type_blob (GMetadata *metadata, } static gboolean +validate_iface_type_blob (GMetadata *metadata, + guint32 offset, + guint32 signature_offset, + gboolean return_type, + GError **error) +{ + InterfaceTypeBlob *blob; + Header *header; + + header = (Header *)metadata->data; + + blob = (InterfaceTypeBlob*)&metadata->data[offset]; + + if (blob->interface == 0 || blob->interface > header->n_entries) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_BLOB, + "Invalid directory index %d", blob->interface); + return FALSE; + } + + return TRUE; +} + +static gboolean validate_param_type_blob (GMetadata *metadata, guint32 offset, guint32 signature_offset, @@ -206,17 +286,17 @@ validate_param_type_blob (GMetadata *metadata, gint n_params, GError **error) { - ParamTypeBlob *blob = (ParamTypeBlob*)&metadata->data[offset]; - TypeHeader *header = (TypeHeader *)&metadata->data[offset]; + ParamTypeBlob *blob; gint i; + blob = (ParamTypeBlob*)&metadata->data[offset]; - if (!header->pointer) + if (!blob->pointer) { g_set_error (error, G_METADATA_ERROR, G_METADATA_ERROR_INVALID_BLOB, - "Pointer type exected for tag %d", header->tag); + "Pointer type exected for tag %d", blob->tag); return FALSE; } @@ -249,39 +329,35 @@ validate_error_type_blob (GMetadata *metadata, GError **error) { ErrorTypeBlob *blob; - TypeHeader *type_header; Header *header; gint i; DirEntry *entry; - guint16 *domain; blob = (ErrorTypeBlob*)&metadata->data[offset]; - type_header = (TypeHeader*)&metadata->data[offset]; header = (Header *)metadata->data; - if (!type_header->pointer) + if (!blob->pointer) { g_set_error (error, G_METADATA_ERROR, G_METADATA_ERROR_INVALID_BLOB, - "Pointer type exected for tag %d", type_header->tag); - return FALSE; + "Pointer type exected for tag %d", blob->tag); + return FALSE; } - domain = (guint16*)&metadata->data[offset + sizeof(ErrorTypeBlob)]; - for (i = 0; i < blob->n_domains; i++, domain++) + for (i = 0; i < blob->n_domains; i++) { - if (*domain == 0 || *domain > header->n_entries) + if (blob->domains[i] == 0 || blob->domains[i] > header->n_entries) { g_set_error (error, G_METADATA_ERROR, G_METADATA_ERROR_INVALID_BLOB, - "Invalid directory index %d", *domain); + "Invalid directory index %d", blob->domains[i]); return FALSE; } - entry = g_metadata_get_dir_entry (metadata, *domain); + entry = g_metadata_get_dir_entry (metadata, blob->domains[i]); if (entry->blob_type != BLOB_TYPE_ERROR_DOMAIN && (entry->local || entry->blob_type != BLOB_TYPE_INVALID)) @@ -305,14 +381,14 @@ validate_type_blob (GMetadata *metadata, GError **error) { SimpleTypeBlob *simple; - TypeHeader *header; - + InterfaceTypeBlob *iface; + simple = (SimpleTypeBlob *)&metadata->data[offset]; - header = (TypeHeader *)&metadata->data[offset]; - if (TYPE_IS_SIMPLE(header->tag)) + if (simple->reserved == 0 && + simple->reserved2 == 0) { - if (header->tag >= TYPE_TAG_ARRAY) + if (simple->tag >= TYPE_TAG_ARRAY) { g_set_error (error, G_METADATA_ERROR, @@ -321,29 +397,31 @@ validate_type_blob (GMetadata *metadata, return FALSE; } - if (header->tag >= TYPE_TAG_UTF8 && - !header->pointer) + if (simple->tag >= TYPE_TAG_UTF8 && + !simple->pointer) { g_set_error (error, G_METADATA_ERROR, G_METADATA_ERROR_INVALID_BLOB, - "Pointer type exected for tag %d", header->tag); - return FALSE; + "Pointer type exected for tag %d", simple->tag); + return FALSE; } return TRUE; } - switch (header->tag) + iface = (InterfaceTypeBlob*)&metadata->data[simple->offset]; + + switch (iface->tag) { case TYPE_TAG_ARRAY: if (!validate_array_type_blob (metadata, simple->offset, signature_offset, return_type, error)) return FALSE; break; - case TYPE_TAG_SYMBOL: - if (!validate_blob (metadata, simple->offset, - error)) + case TYPE_TAG_INTERFACE: + if (!validate_iface_type_blob (metadata, simple->offset, + signature_offset, return_type, error)) return FALSE; break; case TYPE_TAG_LIST: @@ -608,7 +686,6 @@ validate_constant_blob (GMetadata *metadata, 0, 0 }; ConstantBlob *blob; - TypeHeader *header; SimpleTypeBlob *type; if (metadata->len < offset + sizeof (ConstantBlob)) @@ -652,12 +729,11 @@ validate_constant_blob (GMetadata *metadata, "Misaligned constant value"); return FALSE; } - + type = (SimpleTypeBlob *)&metadata->data[offset + G_STRUCT_OFFSET (ConstantBlob, type)]; - header = (TypeHeader *)&metadata->data[offset + G_STRUCT_OFFSET (ConstantBlob, type)]; - if (TYPE_IS_SIMPLE(header->tag)) + if (type->reserved == 0) { - if (header->tag == 0) + if (type->tag == 0) { g_set_error (error, G_METADATA_ERROR, @@ -666,8 +742,8 @@ validate_constant_blob (GMetadata *metadata, return FALSE; } - if (value_size[header->tag] != 0 && - blob->size != value_size[header->tag]) + if (value_size[type->tag] != 0 && + blob->size != value_size[type->tag]) { g_set_error (error, G_METADATA_ERROR, @@ -988,6 +1064,17 @@ validate_struct_blob (GMetadata *metadata, return FALSE; } } + else + { + if (blob->gtype_name || blob->gtype_init) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_BLOB, + "Gtype data in struct"); + return FALSE; + } + } if (metadata->len < offset + sizeof (StructBlob) + blob->n_fields * sizeof (FieldBlob) + @@ -1073,6 +1160,17 @@ validate_enum_blob (GMetadata *metadata, 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)) { diff --git a/girepository/gmetadata.h b/girepository/gmetadata.h index aa41662..a22ee23 100644 --- a/girepository/gmetadata.h +++ b/girepository/gmetadata.h @@ -28,7 +28,6 @@ G_BEGIN_DECLS #define G_IDL_MAGIC "GOBJ\nMETADATA\r\n\032" -#define G_IDL_MAGIC_ESCAPED "GOBJ\\nMETADATA\\r\\n\\032" enum { @@ -96,6 +95,10 @@ typedef struct guint32 offset; } DirEntry; + +#define TYPE_POINTER_MASK 1 << 7 +#define TYPE_TAG_MASK 63 + typedef enum { TYPE_TAG_VOID = 0, @@ -118,34 +121,28 @@ typedef enum TYPE_TAG_DOUBLE = 17, TYPE_TAG_UTF8 = 18, TYPE_TAG_FILENAME = 19, - TYPE_TAG_SYMBOL = 20, - TYPE_TAG_ARRAY = 21, + TYPE_TAG_ARRAY = 20, + TYPE_TAG_INTERFACE = 21, TYPE_TAG_LIST = 22, TYPE_TAG_SLIST = 23, TYPE_TAG_HASH = 24, TYPE_TAG_ERROR = 25 } TypeTag; -typedef struct +typedef union { - guint pointer :1; - guint reserved :2; - guint tag :5; -} TypeHeader; - -#define TYPE_IS_SIMPLE(tAG) (tAG < TYPE_TAG_SYMBOL ? TRUE : FALSE) - -#define TYPE_IS_SYMBOL(tAG) (tAG == TYPE_TAG_SYMBOL ? TRUE : FALSE) - -#define TYPE_IS_COMPLEX(tAG) (tAG > TYPE_TAG_SYMBOL ? TRUE : FALSE) - -typedef struct -{ - TypeHeader header; - + struct + { + guint reserved : 8; + guint reserved2 :16; + guint pointer : 1; + guint reserved3 : 2; + guint tag : 5; + }; guint32 offset; } SimpleTypeBlob; + typedef struct { guint32 name; @@ -174,9 +171,7 @@ typedef struct guint16 n_arguments; -#if 0 ArgBlob arguments[]; -#endif } SignatureBlob; typedef struct @@ -217,13 +212,25 @@ 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; @@ -231,24 +238,26 @@ typedef struct typedef struct { - TypeHeader header; + guint pointer :1; + guint reserved :2; + guint tag :5; guint8 reserved2; guint16 n_types; -#if 0 + SimpleTypeBlob type[]; -#endif } ParamTypeBlob; typedef struct { - TypeHeader header; + guint pointer :1; + guint reserved :2; + guint tag :5; + guint8 reserved2; guint16 n_domains; -#if 0 guint16 domains[]; -#endif } ErrorTypeBlob; typedef struct @@ -362,9 +371,7 @@ typedef struct guint16 n_values; guint16 reserved2; -#if 0 - ValueBlob values[]; -#endif + ValueBlob values[]; } EnumBlob; typedef struct @@ -439,9 +446,10 @@ 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[]; @@ -468,10 +476,10 @@ typedef struct guint16 n_vfuncs; guint16 n_constants; + guint16 prerequisites[]; -#if 0 +#if 0 /* variable-length parts of the blob */ - guint16 prerequisites[]; PropertyBlob properties[]; FunctionBlob methods[]; SignalBlob signals[]; @@ -513,8 +521,11 @@ struct _GMetadata { 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, diff --git a/tests/Makefile.am b/tests/Makefile.am index 8634482..384f052 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = invoke parser +SUBDIRS = . invoke parser EXTRA_DIST = \ roundtrips.sh \ @@ -17,11 +17,4 @@ EXTRA_DIST = \ xref1.test \ xref2.test -TESTS_ENVIRONMENT = \ - LIBTOOL="$(LIBTOOL)" \ - GIREPO_CFLAGS="$(GIREPO_CFLAGS)" \ - GIREPO_LIBS="$(GIREPO_LIBS)" \ - CC="$(CC)" \ - GIREPOPATH="." - TESTS = roundtrips.sh diff --git a/tests/invoke/Makefile.am b/tests/invoke/Makefile.am index 4042321..b56ca4d 100644 --- a/tests/invoke/Makefile.am +++ b/tests/invoke/Makefile.am @@ -5,24 +5,29 @@ testlib_LTLIBRARIES = testfns.la 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="." diff --git a/tests/invoke/invoke-namespace-find.sh b/tests/invoke/invoke-namespace-find.sh new file mode 100755 index 0000000..502dca7 --- /dev/null +++ b/tests/invoke/invoke-namespace-find.sh @@ -0,0 +1,4 @@ +#! /bin/sh +exec ./invoke --namespace-find +#! /bin/sh +exec ./invoke --namespace-find diff --git a/tests/invoke/invoke.c b/tests/invoke/invoke.c index 40aba56..e1e1697 100644 --- a/tests/invoke/invoke.c +++ b/tests/invoke/invoke.c @@ -30,11 +30,24 @@ main (int argc, char *argv[]) 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", diff --git a/tests/roundtrips.sh b/tests/roundtrips.sh index 95eb4ab..65ef78a 100755 --- a/tests/roundtrips.sh +++ b/tests/roundtrips.sh @@ -1,12 +1,26 @@ -#! /bin/sh -x -# -SIMPLE_TESTS="enum.test struct.test constant.test union.test array.test types.test boxed.test errors.test function.test interface.test object.test xref1.test xref2.test" +#! /bin/sh + +SIMPLE_TESTS="array.test boxed.test enum.test errors.test function.test interface.test struct.test union.test" for i in $SIMPLE_TESTS; do - ../tools/g-idl-compiler -o $i.c $srcdir/$i - $LIBTOOL --tag=CC --mode=compile $CC -c $GIREPO_CFLAGS -I$srcdir/../girepository $i.c - $LIBTOOL --tag=CC --mode=link $CC -module -avoid-version -rpath /tmp -o $i.la $i.lo ../girepository/libgirepository.la $GIREPO_LIBS - ../tools/g-idl-generate $i.la > $i.res; - diff -u $srcdir/$i $i.res || exit 1; - rm -f $i.res $i.la $i.lo $i.o $i.c + echo $i + ../tools/g-idl-compiler --raw $srcdir/$i > $i.1; + ../tools/g-idl-generate --raw $i.1 > $i.2; + diff -u $srcdir/$i $i.2 || exit 1; + rm $i.1 $i.2 done + +../tools/g-idl-compiler --raw --module=Foo $srcdir/object.test $srcdir/gobject.test > object.test.1 +../tools/g-idl-generate --raw object.test.1 > object.test.2 +diff -u $srcdir/object.test object.test.2 || exit 1 +rm object.test.1 object.test.2 + +../tools/g-idl-compiler --raw --module=Foo $srcdir/xref1.test $srcdir/xref2.test > xref1.test.1 +../tools/g-idl-generate --raw xref1.test.1 > xref1.test.2 +diff -u $srcdir/xref1.test xref1.test.2 || exit 1 +rm xref1.test.1 xref1.test.2 + +../tools/g-idl-compiler --raw --module=Bar $srcdir/xref1.test $srcdir/xref2.test > xref2.test.1 +../tools/g-idl-generate --raw xref2.test.1 > xref2.test.2 +diff -u $srcdir/xref2.test xref2.test.2 || exit 1 +rm xref2.test.1 xref2.test.2 diff --git a/tools/Makefile.am b/tools/Makefile.am index 545050a..870db83 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -4,32 +4,17 @@ INCLUDES = \ -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 diff --git a/tools/compiler.c b/tools/compiler.c index a73a851..6ab0fa5 100644 --- a/tools/compiler.c +++ b/tools/compiler.c @@ -28,9 +28,113 @@ #include "gidlnode.h" #include "gidlparser.h" #include "gmetadata.h" -#include "gidlcompilercontext.h" -static GLogLevelFlags logged_levels; +gboolean raw = FALSE; +gboolean no_init = FALSE; +gchar **input = NULL; +gchar *output = NULL; +gchar *mname = NULL; +gchar *shlib = NULL; +gboolean debug = FALSE; +gboolean verbose = FALSE; + +static gchar * +format_output (GMetadata *metadata) +{ + GString *result; + gint i; + + result = g_string_sized_new (6 * metadata->len); + + g_string_append_printf (result, "#include \n"); + g_string_append_printf (result, "#include \n\n"); + + g_string_append_printf (result, "const unsigned char _G_METADATA[] = \n{"); + + for (i = 0; i < metadata->len; i++) + { + if (i > 0) + g_string_append (result, ", "); + + if (i % 10 == 0) + g_string_append (result, "\n\t"); + + g_string_append_printf (result, "0x%.2x", metadata->data[i]); + } + + g_string_append_printf (result, "\n};\n\n"); + g_string_append_printf (result, "const gsize _G_METADATA_SIZE = %u;\n\n", + (guint)metadata->len); + + if (!no_init) + { + g_string_append_printf (result, + "__attribute__((constructor)) void\n" + "register_metadata (void)\n" + "{\n" + "\tGMetadata *metadata;\n" + "\tmetadata = g_metadata_new_from_const_memory (_G_METADATA, _G_METADATA_SIZE);\n" + "\tg_irepository_register (NULL, metadata);\n" + "}\n\n"); + + g_string_append_printf (result, + "__attribute__((destructor)) void\n" + "unregister_metadata (void)\n" + "{\n" + "\tg_irepository_unregister (NULL, \"%s\");\n" + "}\n", + g_metadata_get_namespace (metadata)); + } + + return g_string_free (result, FALSE); +} + +static void +write_out_metadata (gchar *prefix, + GMetadata *metadata) +{ + FILE *file; + + if (output == NULL) + file = stdout; + else + { + gchar *filename; + + if (prefix) + filename = g_strdup_printf ("%s-%s", prefix, output); + else + filename = g_strdup (output); + file = g_fopen (filename, "w"); + + if (file == NULL) + { + g_fprintf (stderr, "failed to open '%s': %s\n", + filename, g_strerror (errno)); + g_free (filename); + + return; + } + + g_free (filename); + } + + if (raw) + fwrite (metadata->data, 1, metadata->len, file); + else + { + gchar *code; + + code = format_output (metadata); + fputs (code, file); + g_free (code); + } + + if (output != NULL) + fclose (file); +} + +GLogLevelFlags logged_levels; static void log_handler (const gchar *log_domain, GLogLevelFlags log_level, @@ -42,43 +146,28 @@ static void log_handler (const gchar *log_domain, g_log_default_handler (log_domain, log_level, message, user_data); } +static GOptionEntry options[] = +{ + { "raw", 0, 0, G_OPTION_ARG_NONE, &raw, "emit raw metadata", NULL }, + { "code", 0, G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &raw, "emit C code", NULL }, + { "no-init", 0, 0, G_OPTION_ARG_NONE, &no_init, "do not create _init() function", NULL }, + { "output", 'o', 0, G_OPTION_ARG_FILENAME, &output, "output file", "FILE" }, + { "module", 'm', 0, G_OPTION_ARG_STRING, &mname, "module to compile", "NAME" }, + { "shared-library", 'l', 0, G_OPTION_ARG_FILENAME, &shlib, "shared library", "FILE" }, + { "debug", 0, 0, G_OPTION_ARG_NONE, &debug, "show debug messages", NULL }, + { "verbose", 0, 0, G_OPTION_ARG_NONE, &verbose, "show verbose messages", NULL }, + { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &input, NULL, NULL }, + { NULL, } +}; + int main (int argc, char ** argv) { - gboolean no_init = FALSE; - gchar **input = NULL; - gchar *output = NULL; - gchar *mname = NULL; - gchar *shlib = NULL; - gboolean debug = FALSE; - gboolean verbose = FALSE; - GOptionContext *context; GError *error = NULL; - GList *m, *modules; + GList *c, *m, *modules; gint i; - GList *c; - gint entry_id; - FILE *file; - GIdlCompilerContext *ctx; - GOptionEntry options[] = - { - { "no-init", 0, 0, G_OPTION_ARG_NONE, &no_init, - "do not create _init() function", NULL }, - { "output", 'o', 0, G_OPTION_ARG_FILENAME, &output, - "output file", "FILE" }, - { "module", 'm', 0, G_OPTION_ARG_STRING, &mname, - "module to compile", "NAME" }, - { "shared-library", 'l', 0, G_OPTION_ARG_FILENAME, &shlib, - "shared library", "FILE" }, - { "debug", 0, 0, G_OPTION_ARG_NONE, &debug, - "show debug messages", NULL }, - { "verbose", 0, 0, G_OPTION_ARG_NONE, &verbose, - "show verbose messages", NULL }, - { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &input, - NULL, NULL }, - { NULL, } - }; + g_metadata_check_sanity (); context = g_option_context_new (""); g_option_context_add_main_entries (context, options, NULL); @@ -96,6 +185,7 @@ main (int argc, char ** argv) if (!input) { g_fprintf (stderr, "no input files\n"); + return 1; } @@ -120,8 +210,7 @@ main (int argc, char ** argv) { GIdlModule *module = m->data; gchar *prefix; - GError *err = NULL; - + GMetadata *metadata; if (mname && strcmp (mname, module->name) != 0) continue; @@ -131,71 +220,25 @@ main (int argc, char ** argv) 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) diff --git a/tools/generate.c b/tools/generate.c index f55731e..8c5c3b3 100644 --- a/tools/generate.c +++ b/tools/generate.c @@ -38,8 +38,7 @@ write_type_name (const gchar *namespace, GIBaseInfo *info, FILE *file) { - if (g_base_info_get_namespace (info) != 0 && - strcmp (namespace, g_base_info_get_namespace (info)) != 0) + if (strcmp (namespace, g_base_info_get_namespace (info)) != 0) g_fprintf (file, "%s.", g_base_info_get_namespace (info)); g_fprintf (file, "%s", g_base_info_get_name (info)); @@ -79,11 +78,11 @@ write_type_info (const gchar *namespace, tag = g_type_info_get_tag (info); - if (tag < TYPE_TAG_UTF8) + if (tag < 18) g_fprintf (file, "%s%s", basic[tag], g_type_info_is_pointer (info) ? "*" : ""); - else if (tag <= TYPE_TAG_FILENAME) + else if (tag < 20) g_fprintf (file, "%s", basic[tag]); - else if (tag == TYPE_TAG_ARRAY) + else if (tag == 20) { gint length; @@ -102,7 +101,7 @@ write_type_info (const gchar *namespace, g_fprintf (file, "]"); g_base_info_unref ((GIBaseInfo *)type); } - else if (tag == TYPE_TAG_SYMBOL) + else if (tag == 21) { GIBaseInfo *iface = g_type_info_get_interface (info); write_type_name (namespace, iface, file); @@ -110,7 +109,7 @@ write_type_info (const gchar *namespace, g_fprintf (file, "*"); g_base_info_unref (iface); } - else if (tag == TYPE_TAG_LIST) + else if (tag == 22) { type = g_type_info_get_param_type (info, 0); g_fprintf (file, "GList"); @@ -123,7 +122,7 @@ write_type_info (const gchar *namespace, } g_fprintf (file, "*"); } - else if (tag == TYPE_TAG_SLIST) + else if (tag == 23) { type = g_type_info_get_param_type (info, 0); g_fprintf (file, "GSList"); @@ -136,7 +135,7 @@ write_type_info (const gchar *namespace, } g_fprintf (file, "*"); } - else if (tag == TYPE_TAG_HASH) + else if (tag == 24) { type = g_type_info_get_param_type (info, 0); g_fprintf (file, "GHashTable"); @@ -153,7 +152,7 @@ write_type_info (const gchar *namespace, } g_fprintf (file, "*"); } - else if (tag == TYPE_TAG_ERROR) + else if (tag == 25) { gint n; @@ -532,11 +531,8 @@ write_constant_value (const gchar *namespace, case GI_TYPE_TAG_FILENAME: g_fprintf (file, "%s", value->v_string); break; - case GI_TYPE_TAG_SYMBOL: - g_fprintf (file, "%s", value->v_string); - break; default: - g_warning ("Could not get type tag for constant"); + g_assert_not_reached (); } } @@ -574,22 +570,16 @@ write_enum_info (const gchar *namespace, 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, " -#include -#include -#include - -#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 \n" - "#include \n" - "#include \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; -} diff --git a/tools/gidlcompilercontext.h b/tools/gidlcompilercontext.h deleted file mode 100644 index 5f861a3..0000000 --- a/tools/gidlcompilercontext.h +++ /dev/null @@ -1,131 +0,0 @@ - -#ifndef __G_IDL_COMPILER_CONTEXT_H__ -#define __G_IDL_COMPILER_CONTEXT_H__ - -#include -#include - -#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__*/ diff --git a/tools/gidlcompilerentrynode.c b/tools/gidlcompilerentrynode.c deleted file mode 100644 index f3ea71a..0000000 --- a/tools/gidlcompilerentrynode.c +++ /dev/null @@ -1,1266 +0,0 @@ -/* 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 -#include -#include - -#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); -} diff --git a/tools/gidlcompilerentrynode.h b/tools/gidlcompilerentrynode.h deleted file mode 100644 index da6ac49..0000000 --- a/tools/gidlcompilerentrynode.h +++ /dev/null @@ -1,37 +0,0 @@ -/* 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 - -#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__ */ diff --git a/tools/gidlcompilertypenode.c b/tools/gidlcompilertypenode.c deleted file mode 100644 index ca4e557..0000000 --- a/tools/gidlcompilertypenode.c +++ /dev/null @@ -1,430 +0,0 @@ -/* 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 -#include -#include - -#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)); - } -} diff --git a/tools/gidlcompilertypenode.h b/tools/gidlcompilertypenode.h deleted file mode 100644 index ddc332f..0000000 --- a/tools/gidlcompilertypenode.h +++ /dev/null @@ -1,44 +0,0 @@ -/* 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 - -#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__ */ diff --git a/tools/gidlmodule.c b/tools/gidlmodule.c index c71569f..d17a249 100644 --- a/tools/gidlmodule.c +++ b/tools/gidlmodule.c @@ -1,7 +1,6 @@ /* GObject introspection: Metadata creation * * Copyright (C) 2005 Matthias Clasen - * Copyright (C) 2008 Codethink Ltd * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -25,11 +24,15 @@ #include "gidlmodule.h" #include "gidlnode.h" +#define ALIGN_VALUE(this, boundary) \ + (( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1))) + + GIdlModule * g_idl_module_new (const gchar *name, const gchar *shared_library) { GIdlModule *module; - + module = g_new (GIdlModule, 1); module->name = g_strdup (name); @@ -56,3 +59,157 @@ g_idl_module_free (GIdlModule *module) 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); +} + diff --git a/tools/gidlmodule.h b/tools/gidlmodule.h index f5bb069..3564a75 100644 --- a/tools/gidlmodule.h +++ b/tools/gidlmodule.h @@ -40,6 +40,9 @@ GIdlModule *g_idl_module_new (const gchar *name, 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__ */ diff --git a/tools/gidlnode.c b/tools/gidlnode.c index f6e5f43..0e240b2 100644 --- a/tools/gidlnode.c +++ b/tools/gidlnode.c @@ -26,6 +26,36 @@ #include "gidlnode.h" #include "gmetadata.h" +static gulong string_count = 0; +static gulong unique_string_count = 0; +static gulong string_size = 0; +static gulong unique_string_size = 0; +static gulong types_count = 0; +static gulong unique_types_count = 0; + +void +init_stats (void) +{ + string_count = 0; + unique_string_count = 0; + string_size = 0; + unique_string_size = 0; + types_count = 0; + unique_types_count = 0; +} + +void +dump_stats (void) +{ + g_message ("%lu strings (%lu before sharing), %lu bytes (%lu before sharing)", + unique_string_count, string_count, unique_string_size, string_size); + g_message ("%lu types (%lu before sharing)", unique_types_count, types_count); +} + +#define ALIGN_VALUE(this, boundary) \ + (( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1))) + + GIdlNode * g_idl_node_new (GIdlNodeTypeId type) { @@ -320,6 +350,420 @@ g_idl_node_free (GIdlNode *node) g_free (node); } +/* returns the fixed size of the blob */ +guint32 +g_idl_node_get_size (GIdlNode *node) +{ + GList *l; + gint size, n; + + switch (node->type) + { + case G_IDL_NODE_CALLBACK: + size = 12; + break; + + case G_IDL_NODE_FUNCTION: + size = 16; + break; + + case G_IDL_NODE_PARAM: + size = 12; + break; + + case G_IDL_NODE_TYPE: + size = 4; + break; + + case G_IDL_NODE_OBJECT: + { + GIdlNodeInterface *iface = (GIdlNodeInterface *)node; + + n = g_list_length (iface->interfaces); + size = 32 + 2 * (n + (n % 2)); + + for (l = iface->members; l; l = l->next) + size += g_idl_node_get_size ((GIdlNode *)l->data); + } + break; + + case G_IDL_NODE_INTERFACE: + { + GIdlNodeInterface *iface = (GIdlNodeInterface *)node; + + n = g_list_length (iface->prerequisites); + size = 28 + 2 * (n + (n % 2)); + + for (l = iface->members; l; l = l->next) + size += g_idl_node_get_size ((GIdlNode *)l->data); + } + break; + + case G_IDL_NODE_ENUM: + case G_IDL_NODE_FLAGS: + { + GIdlNodeEnum *enum_ = (GIdlNodeEnum *)node; + + size = 20; + for (l = enum_->values; l; l = l->next) + size += g_idl_node_get_size ((GIdlNode *)l->data); + } + break; + + case G_IDL_NODE_VALUE: + size = 12; + break; + + case G_IDL_NODE_STRUCT: + { + GIdlNodeStruct *struct_ = (GIdlNodeStruct *)node; + + size = 20; + for (l = struct_->members; l; l = l->next) + size += g_idl_node_get_size ((GIdlNode *)l->data); + } + break; + + case G_IDL_NODE_BOXED: + { + GIdlNodeBoxed *boxed = (GIdlNodeBoxed *)node; + + size = 20; + for (l = boxed->members; l; l = l->next) + size += g_idl_node_get_size ((GIdlNode *)l->data); + } + break; + + case G_IDL_NODE_PROPERTY: + size = 12; + break; + + case G_IDL_NODE_SIGNAL: + size = 12; + break; + + case G_IDL_NODE_VFUNC: + size = 16; + break; + + case G_IDL_NODE_FIELD: + size = 12; + break; + + case G_IDL_NODE_CONSTANT: + size = 20; + break; + + case G_IDL_NODE_ERROR_DOMAIN: + size = 16; + break; + + case G_IDL_NODE_XREF: + size = 0; + break; + + case G_IDL_NODE_UNION: + { + GIdlNodeUnion *union_ = (GIdlNodeUnion *)node; + + size = 28; + for (l = union_->members; l; l = l->next) + size += g_idl_node_get_size ((GIdlNode *)l->data); + for (l = union_->discriminators; l; l = l->next) + size += g_idl_node_get_size ((GIdlNode *)l->data); + } + break; + + default: + g_error ("Unhandled node type %d\n", node->type); + size = 0; + } + + g_debug ("node %p type %d size %d", node, node->type, size); + + return size; +} + +/* returns the full size of the blob including variable-size parts */ +guint32 +g_idl_node_get_full_size (GIdlNode *node) +{ + GList *l; + gint size, n; + + g_assert (node != NULL); + + switch (node->type) + { + case G_IDL_NODE_CALLBACK: + { + GIdlNodeFunction *function = (GIdlNodeFunction *)node; + size = 12; + size += ALIGN_VALUE (strlen (node->name) + 1, 4); + for (l = function->parameters; l; l = l->next) + size += g_idl_node_get_full_size ((GIdlNode *)l->data); + size += g_idl_node_get_full_size ((GIdlNode *)function->result); + } + break; + + case G_IDL_NODE_FUNCTION: + { + GIdlNodeFunction *function = (GIdlNodeFunction *)node; + size = 24; + size += ALIGN_VALUE (strlen (node->name) + 1, 4); + size += ALIGN_VALUE (strlen (function->symbol) + 1, 4); + for (l = function->parameters; l; l = l->next) + size += g_idl_node_get_full_size ((GIdlNode *)l->data); + size += g_idl_node_get_full_size ((GIdlNode *)function->result); + } + break; + + case G_IDL_NODE_PARAM: + { + GIdlNodeParam *param = (GIdlNodeParam *)node; + + size = 12; + if (node->name) + size += ALIGN_VALUE (strlen (node->name) + 1, 4); + size += g_idl_node_get_full_size ((GIdlNode *)param->type); + } + break; + + case G_IDL_NODE_TYPE: + { + GIdlNodeType *type = (GIdlNodeType *)node; + if (type->tag < TYPE_TAG_ARRAY) + size = 4; + else + { + switch (type->tag) + { + case TYPE_TAG_ARRAY: + size = 4 + 4; + if (type->parameter_type1) + size += g_idl_node_get_full_size ((GIdlNode *)type->parameter_type1); + break; + case TYPE_TAG_INTERFACE: + size = 4 + 4; + break; + case TYPE_TAG_LIST: + case TYPE_TAG_SLIST: + size = 4 + 4; + if (type->parameter_type1) + size += g_idl_node_get_full_size ((GIdlNode *)type->parameter_type1); + break; + case TYPE_TAG_HASH: + size = 4 + 4 + 4; + if (type->parameter_type1) + size += g_idl_node_get_full_size ((GIdlNode *)type->parameter_type1); + if (type->parameter_type2) + size += g_idl_node_get_full_size ((GIdlNode *)type->parameter_type2); + break; + case TYPE_TAG_ERROR: + { + gint n; + + if (type->errors) + n = g_strv_length (type->errors); + else + n = 0; + + size = 4 + 4 + 2 * (n + n % 2); + } + break; + default: + g_error ("Unknown type tag %d\n", type->tag); + break; + } + } + } + break; + + case G_IDL_NODE_OBJECT: + { + GIdlNodeInterface *iface = (GIdlNodeInterface *)node; + + n = g_list_length (iface->interfaces); + size = 32; + if (iface->parent) + size += ALIGN_VALUE (strlen (iface->parent) + 1, 4); + size += ALIGN_VALUE (strlen (node->name) + 1, 4); + size += ALIGN_VALUE (strlen (iface->gtype_name) + 1, 4); + size += ALIGN_VALUE (strlen (iface->gtype_init) + 1, 4); + size += 2 * (n + (n % 2)); + + for (l = iface->members; l; l = l->next) + size += g_idl_node_get_full_size ((GIdlNode *)l->data); + } + break; + + case G_IDL_NODE_INTERFACE: + { + GIdlNodeInterface *iface = (GIdlNodeInterface *)node; + + n = g_list_length (iface->prerequisites); + size = 28; + size += ALIGN_VALUE (strlen (node->name) + 1, 4); + size += ALIGN_VALUE (strlen (iface->gtype_name) + 1, 4); + size += ALIGN_VALUE (strlen (iface->gtype_init) + 1, 4); + size += 2 * (n + (n % 2)); + + for (l = iface->members; l; l = l->next) + size += g_idl_node_get_full_size ((GIdlNode *)l->data); + } + break; + + case G_IDL_NODE_ENUM: + case G_IDL_NODE_FLAGS: + { + GIdlNodeEnum *enum_ = (GIdlNodeEnum *)node; + + size = 20; + size += ALIGN_VALUE (strlen (node->name) + 1, 4); + if (enum_->gtype_name) + { + size += ALIGN_VALUE (strlen (enum_->gtype_name) + 1, 4); + size += ALIGN_VALUE (strlen (enum_->gtype_init) + 1, 4); + } + + for (l = enum_->values; l; l = l->next) + size += g_idl_node_get_full_size ((GIdlNode *)l->data); + } + break; + + case G_IDL_NODE_VALUE: + { + size = 12; + size += ALIGN_VALUE (strlen (node->name) + 1, 4); + } + break; + + case G_IDL_NODE_STRUCT: + { + GIdlNodeStruct *struct_ = (GIdlNodeStruct *)node; + + size = 20; + size += ALIGN_VALUE (strlen (node->name) + 1, 4); + for (l = struct_->members; l; l = l->next) + size += g_idl_node_get_full_size ((GIdlNode *)l->data); + } + break; + + case G_IDL_NODE_BOXED: + { + GIdlNodeBoxed *boxed = (GIdlNodeBoxed *)node; + + size = 20; + size += ALIGN_VALUE (strlen (node->name) + 1, 4); + if (boxed->gtype_name) + { + size += ALIGN_VALUE (strlen (boxed->gtype_name) + 1, 4); + size += ALIGN_VALUE (strlen (boxed->gtype_init) + 1, 4); + } + for (l = boxed->members; l; l = l->next) + size += g_idl_node_get_full_size ((GIdlNode *)l->data); + } + break; + + case G_IDL_NODE_PROPERTY: + { + GIdlNodeProperty *prop = (GIdlNodeProperty *)node; + + size = 12; + size += ALIGN_VALUE (strlen (node->name) + 1, 4); + size += g_idl_node_get_full_size ((GIdlNode *)prop->type); + } + break; + + case G_IDL_NODE_SIGNAL: + { + GIdlNodeSignal *signal = (GIdlNodeSignal *)node; + + size = 12; + size += ALIGN_VALUE (strlen (node->name) + 1, 4); + for (l = signal->parameters; l; l = l->next) + size += g_idl_node_get_full_size ((GIdlNode *)l->data); + size += g_idl_node_get_full_size ((GIdlNode *)signal->result); + } + break; + + case G_IDL_NODE_VFUNC: + { + GIdlNodeVFunc *vfunc = (GIdlNodeVFunc *)node; + + size = 16; + size += ALIGN_VALUE (strlen (node->name) + 1, 4); + for (l = vfunc->parameters; l; l = l->next) + size += g_idl_node_get_full_size ((GIdlNode *)l->data); + size += g_idl_node_get_full_size ((GIdlNode *)vfunc->result); + } + break; + + case G_IDL_NODE_FIELD: + { + GIdlNodeField *field = (GIdlNodeField *)node; + + size = 12; + size += ALIGN_VALUE (strlen (node->name) + 1, 4); + size += g_idl_node_get_full_size ((GIdlNode *)field->type); + } + break; + + case G_IDL_NODE_CONSTANT: + { + GIdlNodeConstant *constant = (GIdlNodeConstant *)node; + + size = 20; + size += ALIGN_VALUE (strlen (node->name) + 1, 4); + /* FIXME non-string values */ + size += ALIGN_VALUE (strlen (constant->value) + 1, 4); + size += g_idl_node_get_full_size ((GIdlNode *)constant->type); + } + break; + + case G_IDL_NODE_ERROR_DOMAIN: + { + GIdlNodeErrorDomain *domain = (GIdlNodeErrorDomain *)node; + + size = 16; + size += ALIGN_VALUE (strlen (node->name) + 1, 4); + size += ALIGN_VALUE (strlen (domain->getquark) + 1, 4); + } + break; + + case G_IDL_NODE_XREF: + { + GIdlNodeXRef *xref = (GIdlNodeXRef *)node; + + size = 0; + size += ALIGN_VALUE (strlen (node->name) + 1, 4); + size += ALIGN_VALUE (strlen (xref->namespace) + 1, 4); + } + break; + + case G_IDL_NODE_UNION: + { + GIdlNodeUnion *union_ = (GIdlNodeUnion *)node; + + size = 28; + size += ALIGN_VALUE (strlen (node->name) + 1, 4); + for (l = union_->members; l; l = l->next) + size += g_idl_node_get_full_size ((GIdlNode *)l->data); + for (l = union_->discriminators; l; l = l->next) + size += g_idl_node_get_full_size ((GIdlNode *)l->data); + } + break; + + default: + g_error ("Unknown type tag %d\n", node->type); + size = 0; + } + + g_debug ("node %p type %d full size %d", node, node->type, size); + + return size; +} + int g_idl_node_cmp (GIdlNode *node, GIdlNode *other) @@ -519,3 +963,1116 @@ find_entry (GIdlModule *module, 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; +} + diff --git a/tools/gidlnode.h b/tools/gidlnode.h index 3fd4890..32a9a93 100644 --- a/tools/gidlnode.h +++ b/tools/gidlnode.h @@ -307,12 +307,25 @@ struct _GIdlNodeErrorDomain 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); diff --git a/tools/gidlparser.c b/tools/gidlparser.c index deede3c..6a76b2c 100644 --- a/tools/gidlparser.c +++ b/tools/gidlparser.c @@ -268,7 +268,7 @@ parse_type_internal (gchar *str, gchar **rest) } else { - type->tag = TYPE_TAG_SYMBOL; + type->tag = TYPE_TAG_INTERFACE; type->is_interface = TRUE; start = *rest; diff --git a/tools/quote-file.sh b/tools/quote-file.sh deleted file mode 100755 index e720c28..0000000 --- a/tools/quote-file.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/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 -- 2.7.4